Advice on writing a transport

I want to write a new libp2p Transport. Inspired by the discussion and example in go-libp2p-transport-upgrader, I figured the easiest way to get started would be to implement a multiaddr-net address Filter, and then do something like this in my test program:

	sStreamTransport := //what goes here??? - can I just use secio here?
	sMuxTransport := //what goes here??? - can i just use yamux here?
	upgrader := &tptu.Upgrader{		
		Protector: nil,             // don't care about this
		Secure:    sStreamTransport,
		Muxer:     sMuxTransport,
		Filters:   filters,         //will figure this out next once I have basic TCP example working
	}
	tcptrans := simpletransport.NewTCPTransport(upgrader)

	opts := []libp2p.Option{
		libp2p.Security("myfirsttransport",tcptrans),
		[...]
       }

Assuming this all sounds correct, my questions are those in the code above: (1) how do I instantiate secio? and (2) how do I instantiate a stream muxer?

I tried to answer question 1 on my own. Following the “stream security transport” link from the previously mentioned README.md, I wound up in go-libp2p-conn (the repo of interfaces that secio implements), but that didn’t really help me figure out how to “instantiate a secio” in order to pass it into &Upgrader{}'s construction, so that I can then pass the Upgrader into go-libp2p-transport-upgrader.

The best example I could find was actually github.com/OpenBazaar/go-onion-transport, but that’s just the transport itself, not a demonstration of how to use that transport in code. To find that, you have to dig pretty deep into github.com/OpenBazaar/OpenBazaar-go (as noted in issue #1).

Any tips on how to proceed?

To clarify: package simpletransport in my code above is identical to the example in https://github.com/libp2p/go-libp2p-transport-upgrader/blob/master/README.md. Right now I am merely trying to figure out how to get the example to work.

Ok, so my original post is based on some faulty assumptions about who is responsible for providing which objects. The main one is that neither the Transport itself nor the example code using it needs to provide an Upgrader; the Host constructor provides a default Upgrader which includes default values for stream security (currently secio) and stream multiplexers (currently mplex and yamux).

So, the code in my first post should all be removed from the demo program and instead my uninstantiated simpletransport type should be passed to the libp2p Host constructor to replace the default transports [1]. As long as my Transport has a “New…” function, that will be called inside the Host constructor to instantiate the new Transport with an Upgrader owned by the Host. As a Transport author, I never need to worry about this.

[1] Currently these defaults are ws and tcp per this line: https://github.com/libp2p/go-libp2p/blob/d59ca83d48b65c977e19fb16b23c27801dcf7d36/defaults.go#L38

— THESE LINES WERE ALSO RELEVANT IN REVERSE ENGINEERING THIS WHOLE PROCESS —

https://github.com/libp2p/go-tcp-transport/blob/cb705a28822d21c5b0a875b73b36d6767f624fb0/tcp.go#L106 https://github.com/libp2p/go-libp2p/blob/555afdb8a5e577fbcb6f2baf6697eeaebf2f6fc4/config/reflection_magic.go#L95
https://github.com/libp2p/go-libp2p/blob/a5ef3bd89286e6a02b86afaa7eb8443a9e0022b3/config/config.go#L139