Custodial vs Non-custodial Supplier Migration
Custodial vs Non-custodial Supplier Migration
Goal: Provide a clear overview of how Suppliers (Servicers) will migrate from Morse to Shannon.
This document is a result of the GitHub Discussion found here.
Terminology
M
A Morse address controlled by S (both owner and operator)
M_output
A Morse staking (operator and/or owner) address controlled by S_owner
M_operator
A Morse output address (owner) controlled by S_operator (where rewards go)
S
A Shannon address that owns M (both owner and operator)
S_owner
A Shannon owner address (of M_output)
S_operator
A Shannon operator address (of M_operator)
output_address
Morse term - Owner of the staked funds (where rewards and unstaked funds go)
address
Morse term - The Morse staking address (usually the operator address)
owner_address
Shannon term - Owner of the staked funds
operator_address
Shannon term - Operator of the staked funds
Address fields by chain
Chain
Node role
Required field(s)
Optional field(s)
Who can control each field
Morse
NodeRunner (a.k.a Servicer)
address (a.k.a operator)
output_address
address: operator and/or owner
output_address: owner only
Shannon
Supplier
owner_address
operator_address
owner_address: operator and/or owner
operator_address: operator only
Custody Models
Custodial
Owner of staked funds is the same as the node operator
Non-custodial
Owner of staked funds differs from the node operator
Background
Morse Background
In Morse, the CLI provides the following documentation for custodial & non-custodial staking:
Running the following command:
pocket nodes supplier --helpPrints out:
The node namespace handles all node related interactions, from staking and unstaking; to unjailing.
---
Operator Address (i.e. Non-Custodial Address) can do the following:
- Submit Block, Claim & Proof Txs
Output Address (i.e. Custodial Address) can do the following:
- Receive earned rewards
- Receive funds after unstaking
Both Operator and Output Addresses can do the following:
- Submit Stake, EditStake, Unstake, Unjail TxsMorse -> Shannon Migration Types
Migration Types Table
Non-custodial migration has a few variations and can be summarized via the following table.
Flow Type
Supported
Morse (output_address, address)
Shannon (owner_address, operator_address)
Claim Signer
Notes
Pre-Conditions
Custodial #1 – owner-op sign
✅
(M, M)
(S, S)
S & M
Same identity controls and signs Morse & Shannon messages
S owns M
Custodial #2 – operator-only
✅
(null, M)
(S, null)
S & M
Owner signs with no output override
S owns M
Custodial #3 – operator-only
✅
(null, M)
(S, S)
S & M
Same signer, no output override
S owns M
Non-custodial #1 – invalid
❌
(M_output, M_operator)
(S_owner, null)
-
Invalid because operator_address must be specified if output_address ≠ address
—
Non-custodial #2 – owner sign
✅
(M_output, M_operator)
(S_owner, S_operator)
S_owner & M_owner
Owner signs for staking addr; output addr linked off-chain to S_owner
( S_owner owns M_output) && ( S_operator owns M_operator) && ( M_operator gives S_operator shannon staking config offchain)
Non-custodial #3 – operator sign
✅
(M_output, M_operator)
(S_owner, S_operator)
S_operator & M_operator
Operator signs for output addr; off-chain linkage to M_operator required
( S_owner owns M_output) && ( S_operator owns M_operator) && ( S_operator gives M_operator shannon address offline)
Non-custodial #4 – invalid
❌
(M_output, null)
(S_owner, S_operator)
-
Operator address should not be defined if no distinct output address
—
Invalid – missing shannon operator
❌
(M_output, null)
—
-
No operator and no output override — unsupported
—
Invalid – missing shannon owner
❌
—
(null, S_operator)
-
Owner must be defined
—
Non-custodial #5 – invalid
❌
(M1, M2)
(S, S)
S
Owner and operator must differ if output differs from staking address
—
Custodial Migration
Custodial migration is straightforward and can be visualized as follows:
Morse Network -> Transfer (Unstaked Balance) -> Shannon Network
Morse Network -> Transfer (Staked Balance) -> Shannon Network
MsgClaimMorseSupplier transferred to Supplier Address Z where Z = Owner = Operator
(Visual diagram in original doc showing node address A as Addr = Output and Supplier Address Z as Owner = Operator.)
Non-custodial #2 – owner sign
Off-chain controls and sharing of supplier config happen between owner and operator.
Owner signs claim.
Entities / roles:
Owner (controls M_owner / output_address)
Operator (controls M_operator / address)
Servicer: (address, output_address)
Supplier: (owner, operator) → S_owner (owner_address), S_operator (operator_address)
(Original doc shows diagram of owner signing and sharing supplier config offchain.)
Non-custodial #3 – operator sign
Off-chain controls and sharing happen between owner and operator.
Operator signs claim; owner_address is shared with operator.
Entities / roles:
Owner (controls M_owner / output_address)
Operator (controls M_operator / address)
Servicer: (address, output_address)
Supplier: (owner, operator) → S_owner (owner_address), S_operator (operator_address)
(Original doc shows diagram of operator signing claim after receiving owner_address.)
Non-custodial #3 – operator sign - attack
Operator signs claim but replaces the owner with themselves (malicious scenario).
Result: Supplier becomes (operator, operator) — owner replaced with operator.
Entities / roles illustrated:
Owner (intended), Operator (malicious)
M_owner (output_address), M_operator (address)
S_owner (owner_address) ends up being operator in attack scenario
S_operator (operator_address)
(Original doc shows attack diagram where operator substitutes owner.)
Non-custodial #3 – operator vs owner sign risk tradeoffs
Default (operator-led claim)
Owner creates owner_address → shares it → operator submits claim
Low (share one address)
Medium – operator could swap address
Very simple
Yes (recommended)
Operator generates key, gives it to owner
Operator creates key → passes private key to owner → submits claim
Medium
High – private key handled insecurely
Awkward
No
Owner prepares full staking config
Owner sets up both owner_address & operator_address, then hands config to operator
High (many owners are non-technical)
Low
Difficult
No (impractical)
Notes / Preconditions Summary
For non-custodial flows where owner and operator differ, off-chain sharing of addresses or staking configs is required per the migration type.
Certain combinations are invalid (see table) because Shannon requires operator_address if output_address differs from staking address, and owner must be defined.
Was this helpful?
