Transports
A slate has to travel from one wallet to the other and back. The transport is independent of the cryptography, and the resulting transaction is identical whichever route you use. What differs is the operational cost, whether the receiver must be reachable at that moment, and whether every slate field survives the trip.
Send methods: http, file, self, keybase, emoji, epicbox. Listening accepts http, keybase
or epicbox.
Comparison
| Transport | Receiver reachable at send | Needs reachable address | Works behind NAT | Slate version | Payment proofs |
|---|---|---|---|---|---|
epicbox | Not required, the relay stores the slate | No | Yes | V2 always | Not carried |
http | Required | Yes, public URL | No | Negotiated with the listener | Carried |
file | Not required | No | Yes | V3 when the slate uses a V3 field | Carried |
emoji | Not required | No | Yes | V3 when the slate uses a V3 field | Carried |
keybase | Not required | Keybase identity | Yes | Sent without conversion | Carried |
self | Same wallet | No | Yes | n/a | n/a |
Epicbox is the only transport that does not need the receiver reachable at the moment of the send, and the only one that drops a payment proof. Those two columns decide most integrations.
The version column is the reason for the proof column. A payment proof is a V3 slate field.
file and emoji serialise V3 as soon as the slate carries payment_proof or ttl_cutoff_height
(impls/src/adapters/file.rs:30 and
impls/src/adapters/emoji.rs:1151). keybase serialises the slate
without a version conversion, so every field survives
(impls/src/adapters/keybase.rs:304). http asks the listener which
version it speaks and returns an error rather than downgrading a slate that carries a proof
(impls/src/adapters/http.rs:143). epicbox converts to V2
unconditionally (impls/src/adapters/epicbox.rs:251), so the proof
request is gone before the slate leaves. To request a proof, see
choose the transport accordingly.
Observed differences across the three transports a developer reaches for:
| Transport | Commands to complete a transfer | Who must be listening | txs records the counterparty |
|---|---|---|---|
file | 3, split across both wallets | nobody | No, From/To Address is None |
http | 1, sender only | recipient | No, From/To Address is None |
epicbox | 1 command, but both wallets need a subscription | both parties | Yes, the sender's address |
Epicbox needs the sender listening too. send -m epicbox connects to the relay, publishes the
slate, locks its inputs and returns
(controller/src/command.rs:566). It does not wait for the reply. The
signed slate comes back through the relay as a new message, and whichever process holds the sender's
epicbox subscription is what finalises and posts it
(process_incoming_slate()). So
the recipient needs listen -m epicbox to sign, and the sender needs listen -m epicbox to finalise.
Neither has to be connected at the moment the other acts, because the relay stores the message until its
addressee reconnects. Start both subscriptions before sending. An observed round trip took about
1.5 seconds.
Only epicbox tells you who paid you. File and HTTP leave the transaction log's counterparty field empty, so attribution comes from elsewhere in your own system. See exchange integration.
epicbox
A store-and-forward relay. Your wallet holds a WebSocket connection to the relay, and the relay holds slates addressed to you until you reconnect and acknowledge them. It is the only option when neither party can accept inbound connections.
# receiver
epic-wallet listen -m epicbox
# sender
epic-wallet send -m epicbox -d <52-char-key>@epicbox.epiccash.com 1.5
The relay stores signed slates and verifies signatures against the sending address. Slates are not queued indefinitely; see delivery and its limits. After the finalising subscription posts the transaction it waits on the node's mempool, which is why the process can look unresponsive; see the send appears to hang.
The wire protocol is documented in the epicbox reference.
http
The sender posts the slate directly to the receiver's listener. Lowest latency, and it carries every slate V3 field, including payment proofs.
# receiver
epic-wallet listen
# sender
epic-wallet send -m http -d http://receiver.example:3415 1.5
The receiver must be reachable, which means a public host or a port forward.
file
Write the slate to a file, move it by any means, and have the other side process it. It has no network dependency.
epic-wallet send -m file -d slate.tx 1.5 # sender, round 1
epic-wallet receive -m file -i slate.tx # receiver
epic-wallet finalize -m file -i slate.tx.response # sender
Use this for debugging, for moving value between machines you control, and for inspecting exactly what a slate contains.
emoji
The slate encoded as a sequence of emoji, for pasting through a chat application.
The encoding uses a 1,024-entry table, giving 10 bits per glyph. The first glyph is a header encoding how many padding bits were added, so an emoji slate always begins with one of ten specific glyphs. Expect roughly 0.8 glyphs per byte of slate JSON, which is about 3.2 times the byte count once encoded as UTF-8.
Decoding requires the exact glyphs from the table, so a chat client that substitutes or normalises emoji breaks it, and decoding is quadratic in length, so large slates are slow.
keybase
Requires the Keybase client and remains available for compatibility.
self
Both sides of the transfer are the same wallet. Useful for moving value between accounts in one wallet
and for exercising the transaction machinery without a counterparty. --dest names the destination
account.
epic-wallet send -m self -d <destination_account> 1.5
Choosing
| Situation | Use |
|---|---|
| Integration where correctness matters | http on a private network |
| Ordinary users, mobile, intermittent connectivity | epicbox |
| Debugging, or moving value between your own machines | file |
| Payment proofs required | Anything except epicbox |
| Chat-based transfer | emoji |