code: func (cc *Client) prepareHandlerContexts(reqCtx reqContext.Context, request Request, o requestOptions) (*invoke.RequestContext, *invoke.ClientContext, error) {
  
  	if request.ChaincodeID == "" || request.Fcn == "" {
  		return nil, nil, errors.New("ChaincodeID and Fcn are required")
  	}
  
  	transactor, err := cc.context.ChannelService().Transactor(reqCtx)
  	if err != nil {
  		return nil, nil, errors.WithMessage(err, "failed to create transactor")
  	}
  
  	selection, err := cc.context.ChannelService().Selection()
  	if err != nil {
  		return nil, nil, errors.WithMessage(err, "failed to create selection service")
  	}
  
  	discovery, err := cc.context.ChannelService().Discovery()
  	if err != nil {
  		return nil, nil, errors.WithMessage(err, "failed to create discovery service")
  	}
  
  	peerFilter := func(peer fab.Peer) bool {
  		if !cc.greylist.Accept(peer) {
  			return false
  		}
  		if o.TargetFilter != nil && !o.TargetFilter.Accept(peer) {
  			return false
  		}
  		return true
  	}
  
  	var peerSorter selectopts.PeerSorter
  	if o.TargetSorter != nil {
  		peerSorter = func(peers []fab.Peer) []fab.Peer {
  			return o.TargetSorter.Sort(peers)
  		}
  	}
  
  	clientContext := &invoke.ClientContext{
  		Selection:    selection,
  		Discovery:    discovery,
  		Membership:   cc.membership,
  		Transactor:   transactor,
  		EventService: cc.eventService,
  	}
  
  	requestContext := &invoke.RequestContext{
  		Request:         invoke.Request(request),
  		Opts:            invoke.Opts(o),
  		Response:        invoke.Response{},
  		RetryHandler:    retry.New(o.Retry),
  		Ctx:             reqCtx,
  		SelectionFilter: peerFilter,
  		PeerSorter:      peerSorter,
  	}
  
  	return requestContext, clientContext, nil
  }
docs: //prepareHandlerContexts prepares context objects for handlers