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.
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.
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
Use space-data-module-sdk/deployment to work with that payload:
normalizeDeploymentPlan(...)validateDeploymentPlan(...)createDeploymentPlanBundleEntry(...)findDeploymentPlanEntry(...)readDeploymentPlanFromBundle(...)
{
"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
}
]
}{
"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"
}
]
}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.