Protocol installation
This SDK now separates protocol identity from deployment-time routing.
That split matters because module artifacts are portable, compiled, and signable, while deployment endpoints are environment-specific.
Canonical Manifest
Hosted protocol declarations belong in manifest.protocols.
Those declarations describe what a module can host or dial:
protocolIdmethodIdinputPortIdoutputPortIdwireIdtransportKindrolespecUriautoInstalladvertisediscoveryKeydefaultPortrequireSecureTransport
These fields are embedded in the compiled PluginManifest.fbs bytes and are part of the canonical module contract.
Deployment Metadata
Concrete deployment routing does not belong in the canonical manifest.
Examples:
- concrete multiaddrs
- resolved listen ports
- selected peer IDs
- deployment URLs
- interface-keyed input bindings
- scheduler bindings
- hosted service bindings
- request-time auth policy
- publication, pinning, retention, and archive policy
Those values vary per environment and should not change the identity of a signed .wasm artifact.
Instead, attach them as a deployment-plan payload inside the bundle MBL record carried by the appended REC trailer.
Deployment plans should use protocolId as the required identifier for a resolved protocol installation. wireId is optional deployment metadata for legacy transports that still expose it, not a required routing key.
Deployment input and publication bindings should reference manifest.externalInterfaces[].interfaceId. That keeps deployment routing tied to the declared module contract instead of transport-specific topic or wireId hints.
The standard bundle entry is:
entryId:deployment-plansectionName:sds.deploymentpayloadEncoding:json-utf8mediaType:application/vnd.space-data.module.deployment+json
Public Helpers
Use space-data-module-sdk/deployment to work with that payload:
normalizeDeploymentPlan(...)validateDeploymentPlan(...)createDeploymentPlanBundleEntry(...)findDeploymentPlanEntry(...)readDeploymentPlanFromBundle(...)
Example Manifest Protocol
{
"protocols": [
{
"protocolId": "sgp4-stream",
"methodId": "propagate",
"inputPortId": "request",
"outputPortId": "state",
"wireId": "/sdn/sgp4/1.0.0",
"transportKind": "libp2p",
"role": "handle",
"specUri": "https://spacedatastandards.org/#/schemas/PNM",
"autoInstall": true,
"advertise": true,
"discoveryKey": "sgp4-stream",
"defaultPort": 443,
"requireSecureTransport": true
}
]
}Example Deployment Plan
{
"formatVersion": 1,
"pluginId": "com.example.sgp4",
"version": "1.2.3",
"protocolInstallations": [
{
"protocolId": "sgp4-stream",
"transportKind": "libp2p",
"role": "handle",
"peerId": "12D3KooW...",
"listenMultiaddrs": [
"/ip4/127.0.0.1/tcp/14080/ws/p2p/12D3KooW..."
],
"advertisedMultiaddrs": [
"/dns4/sgp4.example.test/tcp/443/wss/p2p/12D3KooW..."
],
"nodeInfoUrl": "https://sgp4.example.test/api/node/info"
}
],
"inputBindings": [
{
"bindingId": "catalog-feed",
"interfaceId": "catalog-pubsub",
"targetMethodId": "propagate",
"targetInputPortId": "request",
"sourceKind": "pubsub"
}
],
"scheduleBindings": [
{
"scheduleId": "poll-upstream",
"bindingMode": "local",
"targetMethodId": "propagate",
"targetInputPortId": "request",
"scheduleKind": "cron",
"cron": "*/15 * * * *"
}
],
"serviceBindings": [
{
"serviceId": "https-query",
"bindingMode": "delegated",
"serviceKind": "http-server",
"routePath": "/api/sgp4",
"method": "GET",
"remoteUrl": "https://gateway.example.test/api/sgp4",
"authPolicyId": "approved-keys"
}
],
"authPolicies": [
{
"policyId": "approved-keys",
"bindingMode": "delegated",
"targetKind": "service",
"targetId": "https-query",
"walletProfileId": "orbpro-default",
"trustMapId": "approved-operators",
"allowServerKeys": ["ed25519:..."]
}
],
"publicationBindings": [
{
"publicationId": "state-catalog",
"interfaceId": "state-catalog-pubsub",
"bindingMode": "local",
"sourceKind": "method-output",
"sourceMethodId": "propagate",
"sourceOutputPortId": "state",
"schemaName": "CAT.fbs",
"emitPnm": true,
"emitFlatbufferArchive": true,
"archivePath": "/data/catalog/cat.bin",
"queryInterfaceId": "state-query-api",
"recordRangeStartField": "startIndex",
"recordRangeStopField": "stopIndex"
}
]
}Identity Rules
wireIdidentifies the network protocol.specUriidentifies the message or schema contract.- multiaddrs identify one deployment instance of that protocol.
interfaceIdidentifies the declared module boundary used by deployment input/publication bindings.- deployment plans should resolve installed protocol surfaces by
protocolId; includewireIdonly when a host integration still needs that legacy hint.
Do not treat those as interchangeable.