11. Create, in the `primitives` folder, a crate with a trait for RPC generation.2 ```rust3 sp_api::decl_runtime_apis! {4 #[api_version(2)]5 pub trait ModuleNameApi<CrossAccountId> 6 where7 CrossAccountId: pallet_evm::account::CrossAccountId<AccountId>,8 {9 fn method_name(user: Option<CrossAccountId>) -> Result<u128, DispatchError>;10 }11 }12 ```13142. client/rpc/src/lib.rs15 * Add a trait with the required methods. Mark it with `#[rpc(server)]` and `#[async_trait]` directives.16 ```rust17 #[rpc(server)]18 #[async_trait]19 pub trait ModuleNameApi<BlockHash, CrossAccountId> {20 #[method(name = "moduleName_methodName")]21 fn method_name(&self, user: Option<CrossAccountId>, at: Option<BlockHash>)22 -> Result<String>;23 }24 ```25 * Don't forget to write the correct method identifier in the form `moduleName_methodName`.26 * Add a structure for which the server API interface will be implemented.27 ```rust28 define_struct_for_server_api!(ModuleName);29 ```30 * Define a macro to be used in the implementation of the server API interface.31 ```rust32 macro_rules! module_api {33 () => {34 dyn ModuleNameRuntimeApi<BlockHash, CrossAccountId>35 };36 }37 ```38 * Implement a server API interface.39 ```rust40 impl<C, Block, CrossAccountId> 41 ModuleNameApiServer<<Block as BlockT>::Hash, CrossAccountId> for ModuleName<C, Block>42 where43 Block: BlockT,44 C: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,45 C::Api: AppPromotionRuntimeApi<Block, BlockNumber, CrossAccountId, AccountId>,46 CrossAccountId: pallet_evm::account::CrossAccountId<AccountId>,47 {48 pass_method!(method_name(user: Option<CrossAccountId>) -> String => |v| v.to_string(), app_promotion_api);49 }50 ```51523. runtime/common/runtime_apis.rs53 * Implement the `ModuleNameApi` interface for `Runtime`. Optionally, you can mark a feature flag to disable the functionality.54 ```rust55 impl MethodApi<Block, BlockNumber, CrossAccountId, AccountId> for Runtime {56 fn method_name(user: Option<CrossAccountId>) -> Result<u128, DispatchError> {57 #[cfg(not(feature = "module"))]58 return unsupported!();5960 #[cfg(feature = "module")]61 return Ok(0);62 }63 }64 ```65664. node/cli/src/service.rs67 * Set the `MethodApi<Block, Runtime::CrossAccountId>` bound in the `start_node_impl`, `start_node`, `start_dev_node` methods.68695. node/rpc/src/lib.rs70 * Add `MethodApi<Block, Runtime::CrossAccountId>` bound to `create_full` method.71 * Enable RPC in the `create_full` method by adding `io.merge(ModuleName::new(client.clone()).into_rpc())?;`72736. Add a new crate (see point 1) into dependencies.74 * client/rpc/Cargo.toml75 * node/rpc/Cargo.toml76 * runtime/opal/Cargo.toml77 * runtime/quartz/Cargo.toml78 * runtime/unique/Cargo.toml79807. Create js-packages/types/ModuleName/definitions.ts and describe the necessary methods in it.81 ```ts82 type RpcParam = {83 name: string;84 type: string;85 isOptional?: true;86 };8788 const CROSS_ACCOUNT_ID_TYPE = 'PalletEvmAccountBasicCrossAccountIdRepr';8990 const fun = (description: string, params: RpcParam[], type: string) => ({91 description,92 params: [...params, atParam],93 type,94 });9596 export default {97 types: {},98 rpc: {99 methodName: fun(100 'Documentation for method',101 [{name: 'user', type: CROSS_ACCOUNT_ID_TYPE, isOptional: true}],102 'u128',103 ),104 },105 };106 ```1071088. Describe definitions from paragraph 7 in js-packages/types/definitions.ts.109 ```ts110 export {default as ModuleName} from './module/definitions';111 ```1121139. js-packages/tests/substrate/substrate-api.ts114 * Set the RPC interface in the `defaultApiOptions` function, add an entry in the `rpc` parameter115 ```ts116 module: defs.module.rpc,117 ```11811910. js-packages/playgrounds/unique.dev.ts120 * Specify RPC interface in `connect` function, add entry in `rpc` parameter121 ```ts122 module: defs.module.rpc,123 ```