Skip to main content

ControlHandler

Trait ControlHandler 

Source
pub trait ControlHandler: Sync {
Show 58 methods // Required methods fn status<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<StatusResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn config_get<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<ConfigResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn config_set_upstream<'life0, 'async_trait>( &'life0 self, params: SetUpstreamParams, ) -> Pin<Box<dyn Future<Output = Result<SetUpstreamResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn log_set_level<'life0, 'async_trait>( &'life0 self, params: SetLevelParams, ) -> Pin<Box<dyn Future<Output = Result<SetLevelResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn cache_get<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<CacheView, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn cache_set_cap<'life0, 'async_trait>( &'life0 self, params: SetCapParams, ) -> Pin<Box<dyn Future<Output = Result<SetCapResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn cache_clear<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<CacheClearResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn hosted_stores_list<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<HostedStoresListResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn hosted_stores_pin<'life0, 'async_trait>( &'life0 self, params: PinParams, ) -> Pin<Box<dyn Future<Output = Result<PinResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn hosted_stores_unpin<'life0, 'async_trait>( &'life0 self, params: UnpinParams, ) -> Pin<Box<dyn Future<Output = Result<UnpinResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn hosted_stores_status<'life0, 'async_trait>( &'life0 self, params: HostedStoreStatusParams, ) -> Pin<Box<dyn Future<Output = Result<HostedStoreStatusResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn capsule_fetch<'life0, 'async_trait>( &'life0 self, params: CapsuleFetchParams, ) -> Pin<Box<dyn Future<Output = Result<CapsuleFetchResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn sync_status<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<SyncStatusResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn sync_trigger<'life0, 'async_trait>( &'life0 self, params: SyncTriggerParams, ) -> Pin<Box<dyn Future<Output = Result<SyncTriggerResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn updater_status<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Value, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn updater_set_channel<'life0, 'async_trait>( &'life0 self, params: SetChannelParams, ) -> Pin<Box<dyn Future<Output = Result<Value, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn updater_pause<'life0, 'async_trait>( &'life0 self, params: PauseParams, ) -> Pin<Box<dyn Future<Output = Result<Value, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn updater_resume<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Value, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn updater_check_now<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Value, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn pairing_list<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Value, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn pairing_approve<'life0, 'async_trait>( &'life0 self, params: ApproveParams, ) -> Pin<Box<dyn Future<Output = Result<PairingApproveResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn pairing_revoke<'life0, 'async_trait>( &'life0 self, params: RevokeParams, ) -> Pin<Box<dyn Future<Output = Result<PairingRevokeResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn peer_status<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Value, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn peers_connect<'life0, 'async_trait>( &'life0 self, params: PeersConnectParams, ) -> Pin<Box<dyn Future<Output = Result<PeersConnectResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn peers_disconnect<'life0, 'async_trait>( &'life0 self, params: PeersDisconnectParams, ) -> Pin<Box<dyn Future<Output = Result<PeersDisconnectResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn chia_peers_add<'life0, 'async_trait>( &'life0 self, params: ChiaPeersAddParams, ) -> Pin<Box<dyn Future<Output = Result<ChiaPeersAddResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn chia_peers_list<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<ChiaPeersListResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn chia_peers_remove<'life0, 'async_trait>( &'life0 self, params: ChiaPeersRemoveParams, ) -> Pin<Box<dyn Future<Output = Result<ChiaPeersRemoveResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn subscribe<'life0, 'async_trait>( &'life0 self, params: SubscribeParams, ) -> Pin<Box<dyn Future<Output = Result<SubscribeResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn unsubscribe<'life0, 'async_trait>( &'life0 self, params: UnsubscribeParams, ) -> Pin<Box<dyn Future<Output = Result<UnsubscribeResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn list_subscriptions<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<ListSubscriptionsResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_balance<'life0, 'async_trait>( &'life0 self, params: WalletBalanceParams, ) -> Pin<Box<dyn Future<Output = Result<WalletBalanceResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_coins<'life0, 'async_trait>( &'life0 self, params: WalletCoinsParams, ) -> Pin<Box<dyn Future<Output = Result<WalletCoinsResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_coin_by_id<'life0, 'async_trait>( &'life0 self, params: WalletCoinByIdParams, ) -> Pin<Box<dyn Future<Output = Result<WalletCoinByIdResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_coin_spend<'life0, 'async_trait>( &'life0 self, params: WalletCoinSpendParams, ) -> Pin<Box<dyn Future<Output = Result<WalletCoinSpendResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_coins_by_parent<'life0, 'async_trait>( &'life0 self, params: WalletCoinsByParentParams, ) -> Pin<Box<dyn Future<Output = Result<WalletCoinsByParentResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_arrivals<'life0, 'async_trait>( &'life0 self, params: WalletArrivalsParams, ) -> Pin<Box<dyn Future<Output = Result<WalletArrivalsResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_peak<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<WalletPeakResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn peer_counts<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<PeerCountsResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_sync_status<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<WalletSyncStatusResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_broadcast<'life0, 'async_trait>( &'life0 self, params: WalletBroadcastParams, ) -> Pin<Box<dyn Future<Output = Result<WalletBroadcastResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_watch<'life0, 'async_trait>( &'life0 self, params: WalletWatchParams, ) -> Pin<Box<dyn Future<Output = Result<WalletWatchResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_unwatch<'life0, 'async_trait>( &'life0 self, params: WalletUnwatchParams, ) -> Pin<Box<dyn Future<Output = Result<WalletUnwatchResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_watched<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<WalletWatchedResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_reservations_held<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<WalletReservationsHeldResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_reservations_reserve<'life0, 'async_trait>( &'life0 self, params: WalletReservationsReserveParams, ) -> Pin<Box<dyn Future<Output = Result<WalletReservationsReserveResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn wallet_reservations_release<'life0, 'async_trait>( &'life0 self, params: WalletReservationsReleaseParams, ) -> Pin<Box<dyn Future<Output = Result<WalletReservationsReleaseResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn spends_list<'life0, 'async_trait>( &'life0 self, params: SpendsListParams, ) -> Pin<Box<dyn Future<Output = Result<SpendsListResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn collateral_requirement<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<CollateralRequirementResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn collateral_margin_get<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<CollateralMarginResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn collateral_margin_set<'life0, 'async_trait>( &'life0 self, params: CollateralMarginSetParams, ) -> Pin<Box<dyn Future<Output = Result<CollateralMarginResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn collateral_buffer<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<CollateralBufferResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn mirror_bond_states<'life0, 'async_trait>( &'life0 self, params: MirrorBondStatesParams, ) -> Pin<Box<dyn Future<Output = Result<MirrorBondStatesResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn profile_put_body<'life0, 'async_trait>( &'life0 self, params: ProfilePutBodyParams, ) -> Pin<Box<dyn Future<Output = Result<ProfilePutBodyResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn profile_get_body<'life0, 'async_trait>( &'life0 self, params: ProfileGetBodyParams, ) -> Pin<Box<dyn Future<Output = Result<ProfileGetBodyResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn pairing_request<'life0, 'async_trait>( &'life0 self, params: RequestParams, ) -> Pin<Box<dyn Future<Output = Result<PairingRequestResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn pairing_poll<'life0, 'async_trait>( &'life0 self, params: PollParams, ) -> Pin<Box<dyn Future<Output = Result<PairingPollResult, ControlError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; // Provided method fn dispatch<'life0, 'async_trait>( &'life0 self, request: JsonRpcRequest, ) -> Pin<Box<dyn Future<Output = JsonRpcResponse> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait { ... }
}
Expand description

The node-facing half of the contract: a running node implements this to SERVE the control surface. Each method is typed to the catalog’s params/results; the provided dispatch routes a raw JsonRpcRequest to the right method so a server needs only one entry point and can never mis-route.

Open/proxied shapes (the updater beacon status, the pairing list, the peer-pool snapshot) return Value rather than a frozen struct, matching the catalog’s ControlCall::Output for those methods.

Required Methods§

Source

fn status<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<StatusResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.status

Source

fn config_get<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<ConfigResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.config.get

Source

fn config_set_upstream<'life0, 'async_trait>( &'life0 self, params: SetUpstreamParams, ) -> Pin<Box<dyn Future<Output = Result<SetUpstreamResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.config.setUpstream

Source

fn log_set_level<'life0, 'async_trait>( &'life0 self, params: SetLevelParams, ) -> Pin<Box<dyn Future<Output = Result<SetLevelResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.log.setLevel

Source

fn cache_get<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<CacheView, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.cache.get

Source

fn cache_set_cap<'life0, 'async_trait>( &'life0 self, params: SetCapParams, ) -> Pin<Box<dyn Future<Output = Result<SetCapResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.cache.setCap

Source

fn cache_clear<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<CacheClearResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.cache.clear

Source

fn hosted_stores_list<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<HostedStoresListResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.hostedStores.list

Source

fn hosted_stores_pin<'life0, 'async_trait>( &'life0 self, params: PinParams, ) -> Pin<Box<dyn Future<Output = Result<PinResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.hostedStores.pin

Source

fn hosted_stores_unpin<'life0, 'async_trait>( &'life0 self, params: UnpinParams, ) -> Pin<Box<dyn Future<Output = Result<UnpinResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.hostedStores.unpin

Source

fn hosted_stores_status<'life0, 'async_trait>( &'life0 self, params: HostedStoreStatusParams, ) -> Pin<Box<dyn Future<Output = Result<HostedStoreStatusResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.hostedStores.status

Source

fn capsule_fetch<'life0, 'async_trait>( &'life0 self, params: CapsuleFetchParams, ) -> Pin<Box<dyn Future<Output = Result<CapsuleFetchResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.capsule.fetch

Source

fn sync_status<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<SyncStatusResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.sync.status

Source

fn sync_trigger<'life0, 'async_trait>( &'life0 self, params: SyncTriggerParams, ) -> Pin<Box<dyn Future<Output = Result<SyncTriggerResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.sync.trigger

Source

fn updater_status<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Value, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.updater.status

Source

fn updater_set_channel<'life0, 'async_trait>( &'life0 self, params: SetChannelParams, ) -> Pin<Box<dyn Future<Output = Result<Value, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.updater.setChannel

Source

fn updater_pause<'life0, 'async_trait>( &'life0 self, params: PauseParams, ) -> Pin<Box<dyn Future<Output = Result<Value, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.updater.pause

Source

fn updater_resume<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Value, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.updater.resume

Source

fn updater_check_now<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Value, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.updater.checkNow

Source

fn pairing_list<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Value, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.pairing.list

Source

fn pairing_approve<'life0, 'async_trait>( &'life0 self, params: ApproveParams, ) -> Pin<Box<dyn Future<Output = Result<PairingApproveResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.pairing.approve

Source

fn pairing_revoke<'life0, 'async_trait>( &'life0 self, params: RevokeParams, ) -> Pin<Box<dyn Future<Output = Result<PairingRevokeResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.pairing.revoke

Source

fn peer_status<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Value, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.peerStatus

Source

fn peers_connect<'life0, 'async_trait>( &'life0 self, params: PeersConnectParams, ) -> Pin<Box<dyn Future<Output = Result<PeersConnectResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.peers.connect

Source

fn peers_disconnect<'life0, 'async_trait>( &'life0 self, params: PeersDisconnectParams, ) -> Pin<Box<dyn Future<Output = Result<PeersDisconnectResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.peers.disconnect

Source

fn chia_peers_add<'life0, 'async_trait>( &'life0 self, params: ChiaPeersAddParams, ) -> Pin<Box<dyn Future<Output = Result<ChiaPeersAddResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.chiaPeers.add — start trusting a Chia full node the operator RUNS.

An implementation MUST write through to the ONE peer store its wallet replica reads; a second peer list is a drift bug waiting to happen.

Three obligations the shell cannot infer from the types:

  • it requires the MASTER token (ControlMethod::requires_master_token). The entry it writes carries authority that outlives the calling token, and control.pairing.revoke does not remove it;
  • params.ip is canonicalised with crate::params::canonical_peer_ip and STORED in that form, so remove and list can match what add wrote;
  • corroboration_bypassed reports the RESULTING trust state and notice carries the node’s own warning verbatim. Reporting a bypass that did not happen tells an operator they configured a node they did not.
Source

fn chia_peers_list<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<ChiaPeersListResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.chiaPeers.list — the tracked Chia full-node peers, banned ones included.

Ordinary token tier: a read that confers nothing, and a paired client that cannot show the operator this list cannot show them the trust state they are subject to.

Source

fn chia_peers_remove<'life0, 'async_trait>( &'life0 self, params: ChiaPeersRemoveParams, ) -> Pin<Box<dyn Future<Output = Result<ChiaPeersRemoveResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.chiaPeers.remove — stop trusting a Chia full node.

MASTER token, like add. This is the ONLY un-trust remedy, so an implementation MUST return results::ChiaPeerRemovalOutcome::NoSuchPeer when nothing matched rather than reporting a removal it did not perform.

Source

fn subscribe<'life0, 'async_trait>( &'life0 self, params: SubscribeParams, ) -> Pin<Box<dyn Future<Output = Result<SubscribeResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.subscribe

params.kind is OPTIONAL on the wire and absent means SubscriptionKind::Capsule. An implementation MUST persist untagged rows it already holds as capsules rather than discarding them: a node that refuses to read its own pre-existing subscriptions.json starts with an empty one, and the upgrade silently unsubscribes the user from everything.

Source

fn unsubscribe<'life0, 'async_trait>( &'life0 self, params: UnsubscribeParams, ) -> Pin<Box<dyn Future<Output = Result<UnsubscribeResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.unsubscribe

Source

fn list_subscriptions<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<ListSubscriptionsResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.listSubscriptions

Source

fn wallet_balance<'life0, 'async_trait>( &'life0 self, params: WalletBalanceParams, ) -> Pin<Box<dyn Future<Output = Result<WalletBalanceResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.balance (READ-only)

Source

fn wallet_coins<'life0, 'async_trait>( &'life0 self, params: WalletCoinsParams, ) -> Pin<Box<dyn Future<Output = Result<WalletCoinsResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.coins (READ-only, OPEN)

An empty coins list MUST mean “a chain was consulted and this address holds nothing”. A read that could not consult a chain MUST return the matching catalogued error instead.

Source

fn wallet_coin_by_id<'life0, 'async_trait>( &'life0 self, params: WalletCoinByIdParams, ) -> Pin<Box<dyn Future<Output = Result<WalletCoinByIdResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.coinById (READ-only, OPEN)

Ok(coin: None) MUST mean “a chain was consulted and holds no such coin”. A read that could not consult a chain MUST return the matching catalogued error instead — a caller that cannot tell those apart reports a spent mint as pending forever.

The params are validated at DESERIALIZATION (lowercase 64-hex, 0x stripped), so any path that decodes WalletCoinByIdParams refuses malformed ids as INVALID_PARAMS before this method is called.

Source

fn wallet_coin_spend<'life0, 'async_trait>( &'life0 self, params: WalletCoinSpendParams, ) -> Pin<Box<dyn Future<Output = Result<WalletCoinSpendResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.coinSpend (READ-only, OPEN)

Ok(spend: None) MUST mean “a chain was consulted and holds no spend of that coin” — the coin is unspent, or unknown. A read that could not consult a chain MUST return the matching catalogued error instead: a caller following a singleton forward reads “no spend” as this is the tip and stops walking, so a failure disguised as absence produces a spend built against a superseded singleton.

A returned spend’s puzzle_reveal MUST tree-hash to the spent coin’s own puzzle_hash, and the implementation MUST fail closed — an error, never an unverified reveal — when it does not or when the reveal will not parse. The reveal comes from a peer, and a peer can lie.

The params are validated at DESERIALIZATION (lowercase 64-hex, 0x stripped), so any path that decodes WalletCoinSpendParams refuses malformed ids as INVALID_PARAMS before this method is called.

Source

fn wallet_coins_by_parent<'life0, 'async_trait>( &'life0 self, params: WalletCoinsByParentParams, ) -> Pin<Box<dyn Future<Output = Result<WalletCoinsByParentResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.coinsByParent (READ-only, OPEN)

Returns the parent’s DIRECT children and nothing further. An implementation MUST NOT recurse: a transitive walk over caller-supplied input is unbounded work the caller cannot bound, and a partial walk returned as a complete one is a lineage with a silent hole in it.

An empty list MUST mean “a chain was consulted and this parent created no known children”. A read that could not consult a chain MUST return the matching catalogued error instead.

The answer is ONE PAGE. An implementation MUST return at most params.effective_limit() records, in ASCENDING coin_id order, starting strictly after params.after_coin_id when one is given; it MUST set complete to whether the page carries the last child; and it MUST set cursor to the last record it actually returned (None for an empty page). It MUST NOT report complete: true on a page it truncated — a caller reads that as the end of a lineage branch. The params are validated at DESERIALIZATION, so an out-of-range page size is refused as INVALID_PARAMS before this method is called.

Every record MUST report asset: None: naming a coin by its parent classifies nothing, and asserting a class this read never verified is a claim a caller would then spend against.

Source

fn wallet_arrivals<'life0, 'async_trait>( &'life0 self, params: WalletArrivalsParams, ) -> Pin<Box<dyn Future<Output = Result<WalletArrivalsResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.arrivals (READ-only, TOKEN-GATED)

Gated although it is a read: the caller supplies only a cursor, so the answer names this node’s OWN watched puzzle hashes and the receive history behind them.

Every returned row MUST be a CONFIRMED arrival that the node itself judged: above its arrival baseline, not previously reported, and not the wallet’s own change. An implementation MUST NOT emit a mempool sighting here, and MUST answer an empty page rather than an error when it has no baseline — “nothing arrived” is the honest answer from a wallet that cannot yet tell history from news.

cursor MUST be the position of the last row actually returned (or the caller’s after_seq for an empty page) and MUST NOT be latest; see WalletArrivalsResult::latest.

Source

fn wallet_peak<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<WalletPeakResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.peak (READ-only, OPEN)

Source

fn peer_counts<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<PeerCountsResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.peerCounts (READ-only, OPEN)

dig_peer_count MUST be dig-node-core’s connected_peers — the same figure control.peerStatus reports — and chia_peer_count MUST be the SAME observation wallet_sync_status reports, served from ONE source so the two answers agree. None means the count cannot be observed; a network that is not running is UNKNOWN, never Some(0).

Source

fn wallet_sync_status<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<WalletSyncStatusResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.syncStatus (READ-only, OPEN)

WalletSyncPhase::Synced MUST require BOTH that the initial catch-up completed and that at least one Chia peer connection is live now, which makes it strictly stronger than WalletPeakResult::synced. peak_height MUST be the node’s OWN replica’s height or None, never an oracle’s, and chia_peer_count counts CHIA full-node peers – never DIG peers.

Source

fn wallet_broadcast<'life0, 'async_trait>( &'life0 self, params: WalletBroadcastParams, ) -> Pin<Box<dyn Future<Output = Result<WalletBroadcastResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.broadcast (TOKEN-GATED)

Pushes an ALREADY-SIGNED bundle: the implementation never signs, and never receives anything it could sign with (§908). A mempool refusal is Ok with accepted: false; failing to reach a mempool is Err.

Source

fn wallet_watch<'life0, 'async_trait>( &'life0 self, params: WalletWatchParams, ) -> Pin<Box<dyn Future<Output = Result<WalletWatchResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.watch (TOKEN-GATED)

Enrols PUBLIC keys for the node’s chain replica to follow. The implementation MUST derive the addresses itself, from the SAME derivation it applies to the keys already in its own custody — a second derivation is a second opinion about which addresses a key covers, and the client would read the difference as missing money.

It MUST be IDEMPOTENT: keys already enrolled are reported as added: 0 and the call succeeds. It MUST persist the enrolment across restarts — a set that evaporates on restart makes a node that syncs today and reports a zero balance tomorrow.

The params are validated at DESERIALIZATION (lowercase 96-hex, 0x stripped), so any path that decodes WalletWatchParams refuses a malformed key as INVALID_PARAMS — for the WHOLE request — before this method is called.

Source

fn wallet_unwatch<'life0, 'async_trait>( &'life0 self, params: WalletUnwatchParams, ) -> Pin<Box<dyn Future<Output = Result<WalletUnwatchResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.unwatch (TOKEN-GATED)

Deregisters keys, and the following MUST actually stop: the addresses leave the replica’s watched set, not merely the list this node reports. A registry that keeps syncing what it says it forgot is the failure this method exists to make impossible.

Deregistering a key that was never enrolled is a success reporting removed: 0.

Source

fn wallet_watched<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<WalletWatchedResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.watched (READ-only, TOKEN-GATED)

Gated although it is a read: the caller supplies nothing, so the answer names this node’s OWN enrolled keys.

MUST return exactly the keys enrolment added, in the wire form they were accepted in, so a client can compare its own set against the node’s by value. MUST NOT include the node’s own custody keys: this method reports what was ENROLLED through it, and a caller reconciling against a superset would unwatch keys it never watched.

Source

fn wallet_reservations_held<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<WalletReservationsHeldResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.reservations.held (READ-only, TOKEN-GATED)

Gated although it is a read: the caller supplies nothing, so the answer names this node’s OWN in-flight commitments.

An implementation MUST read its own clock rather than accept one, MUST omit every reservation that has already lapsed at that instant, and MUST report the clock it used as as_of_unix.

An implementation that cannot read its reservation set MUST return ControlErrorCode::WalletReservationsUnavailable and MUST NOT return an empty list. “Nothing is held” permits a caller to spend; “I cannot tell” must stop it, and the two are indistinguishable once collapsed.

Source

fn wallet_reservations_reserve<'life0, 'async_trait>( &'life0 self, params: WalletReservationsReserveParams, ) -> Pin<Box<dyn Future<Output = Result<WalletReservationsReserveResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.reservations.reserve (TOKEN-GATED)

Acquisition MUST be atomic across concurrent callers: take EVERY coin in coin_ids or take none. On a clash an implementation MUST have written nothing and MUST answer ControlErrorCode::WalletCoinsReserved — never a shortfall code, because the user has the money and is waiting on a settlement, and never a partial success, because a caller believing it holds inputs it does not is the state all-or-none exists to make unreachable.

An empty coin_ids MUST succeed, returning a handle that releases nothing.

The hold MUST expire on its own. An implementation clamps the requested ttl_secs to its own maximum, applies its default when none is given, and MUST report the lifetime it actually applied — a caller told nothing would release on a schedule the node does not keep.

An implementation MUST NOT require, accept or store key material here (§908). A reservation is bookkeeping: it narrows what a selector will choose and authorizes nothing.

Source

fn wallet_reservations_release<'life0, 'async_trait>( &'life0 self, params: WalletReservationsReleaseParams, ) -> Pin<Box<dyn Future<Output = Result<WalletReservationsReleaseResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.wallet.reservations.release (TOKEN-GATED)

Releasing a handle that names no live reservation — lapsed, or already released — MUST be a SUCCESS reporting released: false, never an error. A caller releasing on confirmation cannot know whether the TTL got there first, and an error there teaches callers to discard the result, which is how the release path stops being called at all.

An implementation MUST free every coin the handle holds, or none of them, for the same reason acquisition is all-or-none: a half-freed reservation leaves coins held by a handle the caller has thrown away, and only the TTL would ever recover them.

Source

fn spends_list<'life0, 'async_trait>( &'life0 self, params: SpendsListParams, ) -> Pin<Box<dyn Future<Output = Result<SpendsListResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.spends.list (READ-only, TOKEN-GATED)

One page of the automated-spend audit record — the spends this node made WITHOUT per-transaction approval. Gated although it is a read: the caller names no identifier, so the answer is this node’s OWN spending history.

An implementation MUST NOT let this call initiate, sign, retry, cancel or amend a spend, and MUST NOT expose any control method that edits or deletes an entry. The record replaces authorization with accountability, and an editable record accounts for nothing.

Four obligations, each of which a plausible implementation gets wrong:

  • Report the failure STAGE, never a bare “failed.” Only SpendFailureStage::Signing means the money definitely did not move; a broadcast or confirmation failure is an unknown outcome. An implementation that flattens the stage makes every client structurally unable to tell a person the truth about their money.
  • Keep Unresolved distinct from Failed. It means the node signed and does not know how it ended.
  • State completeness explicitly. complete MUST be false whenever a matching row was withheld, and cursor MUST be the id of the last row actually returned.
  • Report unreadable entries. unreadable_lines MUST count entries the node could not parse; a trail that lost rows must never read as a tidy shorter one. A record that could not be read AT ALL is SpendAuditUnreadable, never an empty page — while a record that was never written IS an empty page, because a node that has never spent automatically is the ordinary case.
Source

fn collateral_requirement<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<CollateralRequirementResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.collateral.requirement (TOKEN-GATED)

This epoch’s derived per-store collateral requirement, with the census inputs behind it.

Gated although the figure itself is derivable from chain by anyone: the UNKNOWN branch names this node’s own census position, and the caller supplies no identifier, so the answer is a fact about this node rather than a relayed public one.

Three obligations, each of which a plausible implementation gets wrong:

  • Answer unknown WITH a reason rather than a number the node does not have. A node that has not censused the epoch, or that sits inside CENSUS_FINALITY_DEPTH_BLOCKS of the tip, MUST return Unknown. It MUST NOT return a zero, a stale epoch’s figure presented as this epoch’s, or an error that a client would render as “no collateral required” — under-posting costs the operator that epoch’s rewards.
  • Report the protocol version that COMPUTED the epoch, not the newest version this build implements. The two differ exactly when a node has upgraded mid-schedule, which is the one case where a client needs to know the difference.
  • Never derive the figure from the local safety margin. The margin MUST NOT reach any value another node derives; required_per_store_dig_base_units is the pre-margin requirement, and a node that returned the margined amount here would make its own preference look like the network’s price.
Source

fn collateral_margin_get<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<CollateralMarginResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.collateral.margin.get (TOKEN-GATED)

The node’s local safety margin in basis points.

A node whose stored configuration predates the field MUST answer DEFAULT_SAFETY_MARGIN_BP, never 0: a zero margin is a deliberate choice to post the requirement exactly, and reporting it for a config that never expressed one tells the operator they opted out of a cushion they never declined.

Source

fn collateral_margin_set<'life0, 'async_trait>( &'life0 self, params: CollateralMarginSetParams, ) -> Pin<Box<dyn Future<Output = Result<CollateralMarginResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.collateral.margin.set (TOKEN-GATED)

Persist the node’s local safety margin and return the margin now in force.

The node is the authoritative home for this setting — the flywheel is headless, so a machine with no GUI must be able to set it — and dig-app is a remote control for the same value.

Two obligations:

  • Persist it, so it survives a restart. A margin that lapses to the default on reboot silently changes what the node posts.
  • Return what was actually stored. The returned margin_bp MUST equal the accepted request’s, because a value above MAX_SAFETY_MARGIN_BP is REFUSED rather than clamped. An implementation that clamped and returned the clamped value would leave the caller’s stored intent and the node’s behaviour disagreeing on the money path.
Source

fn collateral_buffer<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<CollateralBufferResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.collateral.buffer (TOKEN-GATED)

The $DIG this node recommends holding, and its funding position against that figure.

Gated although it is a read, for the same reason control.wallet.watched is: the caller supplies nothing, so the answer is this node’s OWN served set, operator preference and balance — an association, not a relayed public fact.

Four obligations, each of which a plausible implementation gets wrong:

  • Answer unknown WITH a reason rather than a number the node does not have. A zero here reads as no buffer needed — the money lie in its purest form, because an operator acting on it posts nothing and loses the epoch. An implementation MUST NOT substitute a zero, a previous epoch’s buffer presented as this one’s, or an error a client renders as “nothing required”.
  • Count the pairs THIS NODE serves. pairs_served_by_this_node is this node’s own (owner, store, root) set. The census stores figure from control.collateral.requirement is a network-wide advertisement count and MUST NOT be substituted for it; a node that cannot enumerate its own set answers ServedSetUnknown.
  • State the horizon actually used. horizon_epochs and escalation_ceiling_micros MUST describe the headroom this answer contains, not a documented default. Escalation compounds at up to +12.5% per epoch (ESCALATION_UP_STEP_DENOM), so a buffer quoted against an unstated horizon cannot be checked by anyone.
  • Decide the funding state here, once. funding_state is the node’s verdict, not a hint; an implementation that returned a placeholder and left clients to threshold the numbers themselves recreates the rival derivations this method exists to prevent.
Source

fn mirror_bond_states<'life0, 'async_trait>( &'life0 self, params: MirrorBondStatesParams, ) -> Pin<Box<dyn Future<Output = Result<MirrorBondStatesResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.mirror.bondStates (TOKEN-GATED)

The per-(store, root) state of every mirror bond this node holds, and the $DIG they lock.

An implementation MUST:

  • Keep the seven states apart. unfunded is the only genuine out-of-funds state. deferred (no priced requirement), pending (submitted, unconfirmed), withheld (Relayed provenance) and disabled (the node-wide switch) all mean “no coin yet” and none of them means “send money”. Collapsing any of them into unfunded is the dig-app#300 defect this method exists to remove.
  • Read bonded and reclaiming amounts FROM THE COIN, never from this epoch’s requirement. A coin created under a previous requirement locks the previous amount, and the current price is not a fact about an existing coin.
  • Enumerate the SERVED set, not only the desired-bond set. Withheld means a capsule this node holds with Relayed provenance, which is by construction absent from the Held set; a derivation keyed on Held alone can never emit it and silently answers “no such row” where the contract promises “withheld on purpose”. An implementation that CANNOT see provenance MUST answer ProvenanceUnknown for the whole call and MUST NOT return a known page — a page with its withheld rows silently missing claims a completeness the node knows it lacks.
  • Answer Unknown for the WHOLE call when it cannot enumerate its bonds, cannot read chain, cannot read its own in-flight creates, or cannot determine provenance. There is no per-row unknown and no empty-list fallback: entries: [] with complete: true asserts this node holds no bonds, and a partial list read as a complete one hides exactly the bonds nobody is watching.
  • Compute locked_dig_base_units over the WHOLE set, including reclaiming coins, and never over the page. A reclaim in flight still locks its money.
  • Order rows by ascending (store_id, root) and keep that order stable across the pages of one walk, over the LOWERCASE unprefixed hex spelling of both halves, since after means strictly after this key in that order and uppercase hex sorts elsewhere. Set complete explicitly, and set cursor to the key of the LAST row actually handed back (null for an empty page) — never to a position the node “got to”.
Source

fn profile_put_body<'life0, 'async_trait>( &'life0 self, params: ProfilePutBodyParams, ) -> Pin<Box<dyn Future<Output = Result<ProfilePutBodyResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.profile.putBody (TOKEN-GATED)

An implementation MUST independently resolve the profile’s root ON CHAIN, recompute the root of the supplied body, and REFUSE the call unless the two agree and that root is confirmed. The caller’s root is a claim to be checked — never a fact to be trusted — and dig-app gets no exemption: it holds the key and signs the root (§908), but the bytes reach the node the same way a peer’s bytes do, and the same check binds both. An implementation that stores what it is handed makes this node serve arbitrary bytes under someone else’s profile id.

A body whose DECODED length exceeds MAX_BODY_BYTES (4 MiB) MUST be refused as INVALID_PARAMS, before it is persisted: a body larger than that cannot be served to a peer inside dig-gossip’s frame ceiling, so accepting it would store something permanently unsyncable.

Returning Ok therefore asserts BOTH that the root was confirmed on chain and that the body is persisted and servable. A refusal is an error, never an Ok carrying stored: false.

Source

fn profile_get_body<'life0, 'async_trait>( &'life0 self, params: ProfileGetBodyParams, ) -> Pin<Box<dyn Future<Output = Result<ProfileGetBodyResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

control.profile.getBody (READ-only, TOKEN-GATED)

Ok(body_b64: None) MUST mean “this node was consulted and holds no body at that root”. A read that FAILED MUST return a catalogued error instead — a caller that reads a failure as absence renders an existing profile as an empty one.

The returned root MUST be the root the caller asked for; a node MUST NOT substitute a newer body it happens to hold.

Source

fn pairing_request<'life0, 'async_trait>( &'life0 self, params: RequestParams, ) -> Pin<Box<dyn Future<Output = Result<PairingRequestResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

pairing.request (OPEN)

Source

fn pairing_poll<'life0, 'async_trait>( &'life0 self, params: PollParams, ) -> Pin<Box<dyn Future<Output = Result<PairingPollResult, ControlError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

pairing.poll (OPEN)

Provided Methods§

Source

fn dispatch<'life0, 'async_trait>( &'life0 self, request: JsonRpcRequest, ) -> Pin<Box<dyn Future<Output = JsonRpcResponse> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Route a raw JSON-RPC request to the right typed method and build the response envelope.

Deserializes the params for methods that take them, calls the handler, and serializes the typed result. An unknown method → METHOD_NOT_FOUND; malformed params → INVALID_PARAMS. This is the single seam a server dispatches through — the KATs exercise it end-to-end.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§