@ucanto/transport provides encoding, decoding, and transport mechanisms for UCAN-based RPC. It handles the serialization and network communication needed for secure UCAN message exchange between clients and servers.
- CAR Encoding/Decoding: Serializes UCAN messages in Content Addressable Archive format.
- HTTP Transport: Enables UCAN communication over HTTP with proper content negotiation.
- Pluggable Codec System: Supports multiple encoding formats with inbound/outbound codecs.
- Legacy Support: Maintains compatibility with older CBOR-based UCAN message formats.
@ucanto/client: Uses transport to communicate with services.@ucanto/server: Uses transport to receive and respond to requests.@ucanto/core: Provides the UCAN message structures that get transported.@ucanto/interface: Defines transport-related types and interfaces.
For an overview and detailed usage information, refer to the main ucanto README.
npm install @ucanto/transportimport * as HTTP from '@ucanto/transport/http'
import { CAR } from '@ucanto/transport'
import { ed25519 } from '@ucanto/principal'
import { invoke, Message } from '@ucanto/core'
import { DID } from '@ucanto/core'
// Parse the service DID
// SERVICE_DID should be a DID like: did:key:z6Mkk89bC3JrVqKie71YEcc5M1SMVxuCgNx6zLZ8SYJsxALi
const service = DID.parse(process.env.SERVICE_DID)
// Parse the agent's private key
// AGENT_PRIVATE_KEY should be a base64 private key starting with: Mg..
const issuer = ed25519.parse(process.env.AGENT_PRIVATE_KEY)
// Create UCAN invocation
const invocation = invoke({
issuer,
audience: service,
capability: {
can: 'store/add',
with: issuer.did(),
nb: { link: 'bafybeigwflfnv7tjgpuy52ep45cbbgkkb2makd3bwhbj3ueabvt3eq43ca' }
}
})
// Package for transport
const message = await Message.build({ invocations: [invocation] })
const request = await CAR.request.encode(message)
// Create HTTP channel and send to a UCAN service
const channel = HTTP.open({
url: new URL(process.env.SERVICE_URL || 'https://api.example.com')
})
const response = await channel.request(request)
// Unpack response
const replyMessage = await CAR.response.decode(response)
console.log('Received:', replyMessage.receipts.size, 'receipts')For testing, you can use a UCAN server directly as a channel without HTTP. See the @ucanto/server README for examples of using a server as a channel.
AGENT_PRIVATE_KEY Set the key your client should use to sign UCAN invocations. You can generate Ed25519 keys with the ucanto library.
Create a file called generate-keys.js:
import { ed25519 } from '@ucanto/principal'
async function generateKeys() {
const keypair = await ed25519.generate()
const privateKey = ed25519.format(keypair)
console.log('AGENT_PRIVATE_KEY=' + privateKey)
}
generateKeys().catch(console.error)Then run it:
node generate-keys.jsSERVICE_DID Set the DID of the service you want to connect to. Check the service's documentation for their public DID.
SERVICE_URL (Optional)
If you're connecting to a custom service, set both SERVICE_DID and SERVICE_URL environment variables.
For example, Storacha has following SERVICE_DID and SERVICE_URL:
# Storacha uses these default values:
SERVICE_DID="did:web:up.storacha.network"
SERVICE_URL="https://up.storacha.network"Set your environment variables like so:
AGENT_PRIVATE_KEY="your_generated_private_key_here" \
SERVICE_DID="did:key:service_provider_did_here" \Transport provides a codec system for different encoding strategies:
import { Codec, CAR } from '@ucanto/transport'
// Outbound codec (client-side)
const outbound = Codec.outbound({
encoders: { 'application/vnd.ipld.car': CAR.request },
decoders: { 'application/vnd.ipld.car': CAR.response },
})
// Inbound codec (server-side)
const inbound = Codec.inbound({
decoders: { 'application/vnd.ipld.car': CAR.request },
encoders: { 'application/vnd.ipld.car': CAR.response },
})What's happening: Transport handles the low-level details of UCAN communication - encoding messages into CAR format, managing HTTP headers, content negotiation, and error handling. Most developers use @ucanto/client which handles this automatically.
For more details, see the ucanto documentation.