Documentation
¶
Overview ¶
Package pushclient is the client of the anytype-push-server (SYN-47): per-space key derivation, the signed/encrypted request builders, the thin DRPC transport, and the account-level service behind SDK.Push() / space.PushAPI.
The push node is NOT part of the nodeconf — it is a direct out-of-band peer (config.Push) dialed through the regular secure-channel pool, so every RPC carries this account's identity in the handshake (the server authorizes by peer.CtxPubKey).
Trust model (mirrors anytype-heart's core/pushnotification): the server never sees space content or space keys. Each space gets a dedicated ed25519 "push space key" derived from the ACL's first metadata key — topics are signed with it so only members can subscribe/publish, and the server verifies against the raw public key it was handed at CreateSpace time. Notification payloads are encrypted with a symmetric key derived from the space's CURRENT read key, so the server relays opaque ciphertext; receivers pick the decryption key by its sha256 id.
Index ¶
- func DeriveEncKey(readKey crypto.SymKey) (crypto.SymKey, error)
- func DeriveSpaceKey(firstMetadataKey crypto.PrivKey) (crypto.PrivKey, error)
- func EncKeyId(k crypto.SymKey) (string, error)
- func EncodeEncKey(k crypto.SymKey) (string, error)
- func EncodeSpaceKey(k crypto.PrivKey) (string, error)
- type Client
- func (c *Client) CreateSpace(ctx context.Context, req *pushapi.CreateSpaceRequest) error
- func (c *Client) Notify(ctx context.Context, req *pushapi.NotifyRequest) error
- func (c *Client) NotifySilent(ctx context.Context, req *pushapi.NotifyRequest) error
- func (c *Client) RemoveSpace(ctx context.Context, req *pushapi.RemoveSpaceRequest) error
- func (c *Client) RevokeToken(ctx context.Context) error
- func (c *Client) SetToken(ctx context.Context, req *pushapi.SetTokenRequest) error
- func (c *Client) SubscribeAll(ctx context.Context, req *pushapi.SubscribeAllRequest) error
- func (c *Client) Subscriptions(ctx context.Context) (resp *pushapi.SubscriptionsResponse, err error)
- type KeysProvider
- type Service
- func (s *Service) Notify(ctx context.Context, spaceId string, topics []string, payload []byte, ...) error
- func (s *Service) NotifySilent(ctx context.Context, spaceId string, groupId string) error
- func (s *Service) RegisterSpace(ctx context.Context, spaceId string) error
- func (s *Service) RemoveSpace(ctx context.Context, spaceId string) error
- func (s *Service) RevokeToken(ctx context.Context) error
- func (s *Service) SetToken(ctx context.Context, platform space.PushPlatform, token string) error
- func (s *Service) SubscribeAll(ctx context.Context, subs []space.PushSpaceTopics) error
- func (s *Service) Subscriptions(ctx context.Context) ([]space.PushSubscription, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DeriveEncKey ¶
DeriveEncKey derives the notification-payload encryption key from the space's CURRENT read key (aclState.CurrentReadKey). Unlike the space key it rotates with the read key — receivers resolve which key to decrypt with via the message's KeyId (EncKeyId), so a rotation mid-flight only costs a miss on messages encrypted under the old key.
func DeriveSpaceKey ¶
DeriveSpaceKey derives the per-space push signing key from the ACL's FIRST metadata key (aclState.FirstMetadataKey — fixed at space creation, never rotates, held by every member). Its raw public key is the space's identity on the push server: Topic.SpaceKey and CreateSpace/RemoveSpace.SpaceKey; the private half signs topics and the space-registration account signature.
func EncKeyId ¶
EncKeyId is the wire identifier of a payload encryption key: hex(sha256(rawKeyBytes)). Stamped into pushapi.Message.KeyId so a receiver holding several derived keys (read-key rotations) can pick the right one without trial decryption.
func EncodeEncKey ¶
EncodeEncKey packs the derived payload encryption key into its receiver-cache wire form: base64 (std) of the raw AES key bytes — byte-compatible with anytype-heart's spacePushNotificationEncryptionKey space-view detail.
func EncodeSpaceKey ¶
EncodeSpaceKey packs the derived push signing key into its receiver-cache wire form: base64 (std) of the protobuf-marshalled private key — byte-compatible with anytype-heart's spacePushNotificationKey space-view detail, so client-side decode code is portable between the two stacks.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client speaks pushproto.Push to a single configured push node. Safe for concurrent use.
func NewClient ¶
NewClient builds a Client bound to the push node's peerId. The peer's dial addresses must already be registered on the peer service (App.SetPeerAddrs) — the push node is not in the nodeconf.
func (*Client) CreateSpace ¶
CreateSpace registers a space push key with the server.
func (*Client) NotifySilent ¶
NotifySilent publishes a data-only wakeup (no message body).
func (*Client) RemoveSpace ¶
RemoveSpace unregisters a space push key.
func (*Client) RevokeToken ¶
RevokeToken drops this device's token.
func (*Client) SubscribeAll ¶
SubscribeAll replaces the account's entire topic set.
func (*Client) Subscriptions ¶
func (c *Client) Subscriptions(ctx context.Context) (resp *pushapi.SubscriptionsResponse, err error)
Subscriptions lists the account's current topic set.
type KeysProvider ¶
type KeysProvider interface {
PushKeys(ctx context.Context, spaceId string) (spaceKey crypto.PrivKey, encKey crypto.SymKey, err error)
}
KeysProvider resolves a space's push keys from its ACL: the derived push signing key (from the first metadata key — fixed for the space's life) and the payload encryption key (from the CURRENT read key — rotates with it). Implemented by spaceimpl.Service.PushKeys.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service implements space.PushAPI. Always constructed by sdk.Open; when no push node is configured client is nil and every method returns space.ErrPushNotConfigured — so embedders can hold the handle unconditionally and gate on the error, not on nil.
func NewService ¶
func NewService(client *Client, keys KeysProvider, account *accountdata.AccountKeys) *Service
NewService builds the push service. client may be nil (push node not configured); keys and account must be non-nil.
func (*Service) Notify ¶
func (s *Service) Notify(ctx context.Context, spaceId string, topics []string, payload []byte, groupId string) error
Notify publishes an encrypted, account-signed notification to the given topics within spaceId.
func (*Service) NotifySilent ¶
NotifySilent wakes the account's own other devices: a body-less notify on the caller's own-identity topic within spaceId (the only topic the server accepts on the silent path).
func (*Service) RegisterSpace ¶
RegisterSpace registers the space's derived push key with the server. Tolerates pushapi.ErrSpaceExists for idempotency (the current server always answers Ok, but older/stricter deployments may signal the duplicate).
func (*Service) RemoveSpace ¶
RemoveSpace unregisters the space's push key.
func (*Service) RevokeToken ¶
RevokeToken drops this device's push token.
func (*Service) SubscribeAll ¶
SubscribeAll replaces the account's ENTIRE topic set (full replace — see space.PushAPI). Topics for every space are signed with that space's push key and submitted in one request.
Per-space degrade, not all-or-nothing: a space whose push keys can't be derived (removed from the ACL → read key rotated away, storage not yet materialized, never-completable invite) is SKIPPED with a warning instead of failing the call — one bad space must not freeze the account's whole subscription state. Because the request is a full replace, skipping also unsubscribes the keyless space's stale topics — matching heart, whose keyless spaces contribute no topics (spaceTopicsCollection.SetSpaceViewStatus early-returns on nil keys).
func (*Service) Subscriptions ¶
Subscriptions returns the account's current topic set as raw {base58 spaceKey, topic} rows. The server strips signatures.