From 6089ba23903d6679b7ca7ed2878aec94c069df68 Mon Sep 17 00:00:00 2001
From: Alena Petraki <alena.petraki@gmail.com>
Date: Wed, 24 May 2023 13:58:54 +0300
Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?=
 =?UTF-8?q?=D0=B2=D0=B0=D0=BD=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=BE=D1=81?=
 =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D1=81=D1=82=D1=80=D0=B0=D0=BD=D1=81=D1=82?=
 =?UTF-8?q?=D0=B2=20=D0=BC=D0=B5=D0=B6=D0=B4=D1=83=20=D0=BE=D1=80=D0=B3?=
 =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=D0=BC=D0=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 go.mod                                        |   8 +-
 go.sum                                        |   8 +-
 perxis-proto                                  |   2 +-
 pkg/spaces/middleware/caching_middleware.go   |  43 ++
 .../middleware/error_logging_middleware.go    |  40 ++
 pkg/spaces/middleware/logging_middleware.go   | 146 +++++
 .../middleware/recovering_middleware.go       |  52 +-
 pkg/spaces/middleware/telemetry_middleware.go |  86 ++-
 pkg/spaces/mocks/Spaces.go                    |  85 ++-
 pkg/spaces/mocks/Storage.go                   |  21 +-
 pkg/spaces/service.go                         |  17 +
 pkg/spaces/space.go                           |  18 +-
 pkg/spaces/storage.go                         |   9 +-
 pkg/spaces/transport/client.go                |  39 ++
 pkg/spaces/transport/endpoints.microgen.go    |  16 +-
 pkg/spaces/transport/exchanges.microgen.go    |  26 +
 pkg/spaces/transport/grpc/client.go           |  17 +-
 pkg/spaces/transport/grpc/client.microgen.go  |  28 +
 .../protobuf_endpoint_converters.microgen.go  | 118 ++++
 pkg/spaces/transport/grpc/server.go           |  16 +-
 pkg/spaces/transport/grpc/server.microgen.go  |  72 ++-
 pkg/spaces/transport/server.microgen.go       |  48 +-
 proto/spaces/spaces.pb.go                     | 595 ++++++++++++++----
 proto/spaces/spaces_grpc.pb.go                | 197 +++++-
 24 files changed, 1504 insertions(+), 203 deletions(-)

diff --git a/go.mod b/go.mod
index b3222c89..0efbbd17 100644
--- a/go.mod
+++ b/go.mod
@@ -16,13 +16,14 @@ require (
 	github.com/rs/xid v1.4.0
 	github.com/stretchr/testify v1.8.2
 	go.mongodb.org/mongo-driver v1.11.4
-	go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.40.0
+	go.opentelemetry.io/otel v1.14.0
+	go.opentelemetry.io/otel/trace v1.14.0
 	go.uber.org/zap v1.19.1
 	golang.org/x/crypto v0.8.0
 	golang.org/x/net v0.9.0
 	golang.org/x/oauth2 v0.4.0
 	google.golang.org/grpc v1.54.0
-	google.golang.org/protobuf v1.28.1
+	google.golang.org/protobuf v1.30.0
 	gopkg.in/yaml.v3 v3.0.1
 )
 
@@ -51,9 +52,6 @@ require (
 	github.com/xdg-go/scram v1.1.1 // indirect
 	github.com/xdg-go/stringprep v1.0.3 // indirect
 	github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
-	go.opentelemetry.io/otel v1.14.0 // indirect
-	go.opentelemetry.io/otel/metric v0.37.0 // indirect
-	go.opentelemetry.io/otel/trace v1.14.0 // indirect
 	go.uber.org/atomic v1.9.0 // indirect
 	go.uber.org/multierr v1.7.0 // indirect
 	golang.org/x/sync v0.1.0 // indirect
diff --git a/go.sum b/go.sum
index b7913ca0..e83ee408 100644
--- a/go.sum
+++ b/go.sum
@@ -124,12 +124,8 @@ github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7Jul
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 go.mongodb.org/mongo-driver v1.11.4 h1:4ayjakA013OdpGyL2K3ZqylTac/rMjrJOMZ1EHizXas=
 go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.40.0 h1:5jD3teb4Qh7mx/nfzq4jO2WFFpvXD0vYWFDrdvNWmXk=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.40.0/go.mod h1:UMklln0+MRhZC4e3PwmN3pCtq4DyIadWw4yikh6bNrw=
 go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
 go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
-go.opentelemetry.io/otel/metric v0.37.0 h1:pHDQuLQOZwYD+Km0eb657A25NaRzy0a+eLyKfDXedEs=
-go.opentelemetry.io/otel/metric v0.37.0/go.mod h1:DmdaHfGt54iV6UKxsV9slj2bBRJcKC1B1uvDLIioc1s=
 go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
 go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
@@ -201,8 +197,8 @@ google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
 google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
-google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
+google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/perxis-proto b/perxis-proto
index e0c174cd..53a6df87 160000
--- a/perxis-proto
+++ b/perxis-proto
@@ -1 +1 @@
-Subproject commit e0c174cd26694f42fbb65eb4d2c86fdcd1fcbbf0
+Subproject commit 53a6df870f5695939261f5cb6914c13090a4047b
diff --git a/pkg/spaces/middleware/caching_middleware.go b/pkg/spaces/middleware/caching_middleware.go
index 720347d6..d659cf3a 100644
--- a/pkg/spaces/middleware/caching_middleware.go
+++ b/pkg/spaces/middleware/caching_middleware.go
@@ -104,3 +104,46 @@ func (m cachingMiddleware) Delete(ctx context.Context, spaceId string) (err erro
 	}
 	return err
 }
+
+func (m cachingMiddleware) Transfer(ctx context.Context, spaceID, transferToOrg string) error {
+	err := m.next.Transfer(ctx, spaceID, transferToOrg)
+	if err == nil {
+		value, e := m.cache.Get(spaceID)
+		if e == nil {
+			space := value.(*service.Space)
+			m.cache.Remove(orgKey(space.OrgID))
+		}
+		m.cache.Remove(spaceID)
+	}
+	return err
+}
+
+func (m cachingMiddleware) AbortTransfer(ctx context.Context, spaceID string) error {
+	err := m.next.AbortTransfer(ctx, spaceID)
+	if err == nil {
+		value, e := m.cache.Get(spaceID)
+		if e == nil {
+			space := value.(*service.Space)
+			m.cache.Remove(orgKey(space.OrgID))
+		}
+		m.cache.Remove(spaceID)
+	}
+	return err
+}
+
+func (m cachingMiddleware) ListTransfers(ctx context.Context, orgID string) (spaces []*service.Space, err error) {
+	return m.next.ListTransfers(ctx, orgID)
+}
+
+func (m cachingMiddleware) AcceptTransfer(ctx context.Context, spaceID string) error {
+	err := m.next.AcceptTransfer(ctx, spaceID)
+	if err == nil {
+		value, e := m.cache.Get(spaceID)
+		if e == nil {
+			space := value.(*service.Space)
+			m.cache.Remove(orgKey(space.OrgID))
+		}
+		m.cache.Remove(spaceID)
+	}
+	return err
+}
diff --git a/pkg/spaces/middleware/error_logging_middleware.go b/pkg/spaces/middleware/error_logging_middleware.go
index 4f352476..809d3df4 100644
--- a/pkg/spaces/middleware/error_logging_middleware.go
+++ b/pkg/spaces/middleware/error_logging_middleware.go
@@ -29,6 +29,26 @@ func ErrorLoggingMiddleware(logger *zap.Logger) Middleware {
 	}
 }
 
+func (m *errorLoggingMiddleware) AbortTransfer(ctx context.Context, spaceID string) (err error) {
+	logger := m.logger
+	defer func() {
+		if err != nil {
+			logger.Warn("response error", zap.Error(err))
+		}
+	}()
+	return m.next.AbortTransfer(ctx, spaceID)
+}
+
+func (m *errorLoggingMiddleware) AcceptTransfer(ctx context.Context, spaceID string) (err error) {
+	logger := m.logger
+	defer func() {
+		if err != nil {
+			logger.Warn("response error", zap.Error(err))
+		}
+	}()
+	return m.next.AcceptTransfer(ctx, spaceID)
+}
+
 func (m *errorLoggingMiddleware) Create(ctx context.Context, space *spaces.Space) (created *spaces.Space, err error) {
 	logger := m.logger
 	defer func() {
@@ -69,6 +89,26 @@ func (m *errorLoggingMiddleware) List(ctx context.Context, orgId string) (spaces
 	return m.next.List(ctx, orgId)
 }
 
+func (m *errorLoggingMiddleware) ListTransfers(ctx context.Context, orgID string) (spaces []*spaces.Space, err error) {
+	logger := m.logger
+	defer func() {
+		if err != nil {
+			logger.Warn("response error", zap.Error(err))
+		}
+	}()
+	return m.next.ListTransfers(ctx, orgID)
+}
+
+func (m *errorLoggingMiddleware) Transfer(ctx context.Context, spaceID string, transferToOrg string) (err error) {
+	logger := m.logger
+	defer func() {
+		if err != nil {
+			logger.Warn("response error", zap.Error(err))
+		}
+	}()
+	return m.next.Transfer(ctx, spaceID, transferToOrg)
+}
+
 func (m *errorLoggingMiddleware) Update(ctx context.Context, space *spaces.Space) (err error) {
 	logger := m.logger
 	defer func() {
diff --git a/pkg/spaces/middleware/logging_middleware.go b/pkg/spaces/middleware/logging_middleware.go
index 9a379099..71ea716e 100644
--- a/pkg/spaces/middleware/logging_middleware.go
+++ b/pkg/spaces/middleware/logging_middleware.go
@@ -33,6 +33,78 @@ func LoggingMiddleware(logger *zap.Logger) Middleware {
 	}
 }
 
+func (m *loggingMiddleware) AbortTransfer(ctx context.Context, spaceID string) (err error) {
+	begin := time.Now()
+	var fields []zapcore.Field
+	for k, v := range map[string]interface{}{
+		"ctx":     ctx,
+		"spaceID": spaceID} {
+		if k == "ctx" {
+			fields = append(fields, zap.String("principal", fmt.Sprint(auth.GetPrincipal(ctx))))
+			continue
+		}
+		fields = append(fields, zap.Reflect(k, v))
+	}
+
+	m.logger.Debug("AbortTransfer.Request", fields...)
+
+	err = m.next.AbortTransfer(ctx, spaceID)
+
+	fields = []zapcore.Field{
+		zap.Duration("time", time.Since(begin)),
+	}
+
+	for k, v := range map[string]interface{}{
+		"err": err} {
+		if k == "err" {
+			err, _ := v.(error)
+			fields = append(fields, zap.Error(err))
+			continue
+		}
+		fields = append(fields, zap.Reflect(k, v))
+	}
+
+	m.logger.Debug("AbortTransfer.Response", fields...)
+
+	return err
+}
+
+func (m *loggingMiddleware) AcceptTransfer(ctx context.Context, spaceID string) (err error) {
+	begin := time.Now()
+	var fields []zapcore.Field
+	for k, v := range map[string]interface{}{
+		"ctx":     ctx,
+		"spaceID": spaceID} {
+		if k == "ctx" {
+			fields = append(fields, zap.String("principal", fmt.Sprint(auth.GetPrincipal(ctx))))
+			continue
+		}
+		fields = append(fields, zap.Reflect(k, v))
+	}
+
+	m.logger.Debug("AcceptTransfer.Request", fields...)
+
+	err = m.next.AcceptTransfer(ctx, spaceID)
+
+	fields = []zapcore.Field{
+		zap.Duration("time", time.Since(begin)),
+	}
+
+	for k, v := range map[string]interface{}{
+		"err": err} {
+		if k == "err" {
+			err, _ := v.(error)
+			fields = append(fields, zap.Error(err))
+			continue
+		}
+		fields = append(fields, zap.Reflect(k, v))
+	}
+
+	m.logger.Debug("AcceptTransfer.Response", fields...)
+
+	return err
+}
+
 func (m *loggingMiddleware) Create(ctx context.Context, space *spaces.Space) (created *spaces.Space, err error) {
 	begin := time.Now()
 	var fields []zapcore.Field
@@ -180,6 +252,80 @@ func (m *loggingMiddleware) List(ctx context.Context, orgId string) (spaces []*s
 	return spaces, err
 }
 
+func (m *loggingMiddleware) ListTransfers(ctx context.Context, orgID string) (spaces []*spaces.Space, err error) {
+	begin := time.Now()
+	var fields []zapcore.Field
+	for k, v := range map[string]interface{}{
+		"ctx":   ctx,
+		"orgID": orgID} {
+		if k == "ctx" {
+			fields = append(fields, zap.String("principal", fmt.Sprint(auth.GetPrincipal(ctx))))
+			continue
+		}
+		fields = append(fields, zap.Reflect(k, v))
+	}
+
+	m.logger.Debug("ListTransfers.Request", fields...)
+
+	spaces, err = m.next.ListTransfers(ctx, orgID)
+
+	fields = []zapcore.Field{
+		zap.Duration("time", time.Since(begin)),
+	}
+
+	for k, v := range map[string]interface{}{
+		"spaces": spaces,
+		"err":    err} {
+		if k == "err" {
+			err, _ := v.(error)
+			fields = append(fields, zap.Error(err))
+			continue
+		}
+		fields = append(fields, zap.Reflect(k, v))
+	}
+
+	m.logger.Debug("ListTransfers.Response", fields...)
+
+	return spaces, err
+}
+
+func (m *loggingMiddleware) Transfer(ctx context.Context, spaceID string, transferToOrg string) (err error) {
+	begin := time.Now()
+	var fields []zapcore.Field
+	for k, v := range map[string]interface{}{
+		"ctx":           ctx,
+		"spaceID":       spaceID,
+		"transferToOrg": transferToOrg} {
+		if k == "ctx" {
+			fields = append(fields, zap.String("principal", fmt.Sprint(auth.GetPrincipal(ctx))))
+			continue
+		}
+		fields = append(fields, zap.Reflect(k, v))
+	}
+
+	m.logger.Debug("Transfer.Request", fields...)
+
+	err = m.next.Transfer(ctx, spaceID, transferToOrg)
+
+	fields = []zapcore.Field{
+		zap.Duration("time", time.Since(begin)),
+	}
+
+	for k, v := range map[string]interface{}{
+		"err": err} {
+		if k == "err" {
+			err, _ := v.(error)
+			fields = append(fields, zap.Error(err))
+			continue
+		}
+		fields = append(fields, zap.Reflect(k, v))
+	}
+
+	m.logger.Debug("Transfer.Response", fields...)
+
+	return err
+}
+
 func (m *loggingMiddleware) Update(ctx context.Context, space *spaces.Space) (err error) {
 	begin := time.Now()
 	var fields []zapcore.Field
diff --git a/pkg/spaces/middleware/recovering_middleware.go b/pkg/spaces/middleware/recovering_middleware.go
index cb983bdb..c5784c1a 100644
--- a/pkg/spaces/middleware/recovering_middleware.go
+++ b/pkg/spaces/middleware/recovering_middleware.go
@@ -1,9 +1,9 @@
+package middleware
+
 // Code generated by gowrap. DO NOT EDIT.
 // template: ../../../assets/templates/middleware/recovery
 // gowrap: http://github.com/hexdigest/gowrap
 
-package middleware
-
 //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/spaces -i Spaces -t ../../../assets/templates/middleware/recovery -o recovering_middleware.go -l ""
 
 import (
@@ -30,6 +30,30 @@ func RecoveringMiddleware(logger *zap.Logger) Middleware {
 	}
 }
 
+func (m *recoveringMiddleware) AbortTransfer(ctx context.Context, spaceID string) (err error) {
+	logger := m.logger
+	defer func() {
+		if r := recover(); r != nil {
+			logger.Error("panic", zap.Error(fmt.Errorf("%v", r)))
+			err = fmt.Errorf("%v", r)
+		}
+	}()
+
+	return m.next.AbortTransfer(ctx, spaceID)
+}
+
+func (m *recoveringMiddleware) AcceptTransfer(ctx context.Context, spaceID string) (err error) {
+	logger := m.logger
+	defer func() {
+		if r := recover(); r != nil {
+			logger.Error("panic", zap.Error(fmt.Errorf("%v", r)))
+			err = fmt.Errorf("%v", r)
+		}
+	}()
+
+	return m.next.AcceptTransfer(ctx, spaceID)
+}
+
 func (m *recoveringMiddleware) Create(ctx context.Context, space *spaces.Space) (created *spaces.Space, err error) {
 	logger := m.logger
 	defer func() {
@@ -78,6 +102,30 @@ func (m *recoveringMiddleware) List(ctx context.Context, orgId string) (spaces [
 	return m.next.List(ctx, orgId)
 }
 
+func (m *recoveringMiddleware) ListTransfers(ctx context.Context, orgID string) (spaces []*spaces.Space, err error) {
+	logger := m.logger
+	defer func() {
+		if r := recover(); r != nil {
+			logger.Error("panic", zap.Error(fmt.Errorf("%v", r)))
+			err = fmt.Errorf("%v", r)
+		}
+	}()
+
+	return m.next.ListTransfers(ctx, orgID)
+}
+
+func (m *recoveringMiddleware) Transfer(ctx context.Context, spaceID string, transferToOrg string) (err error) {
+	logger := m.logger
+	defer func() {
+		if r := recover(); r != nil {
+			logger.Error("panic", zap.Error(fmt.Errorf("%v", r)))
+			err = fmt.Errorf("%v", r)
+		}
+	}()
+
+	return m.next.Transfer(ctx, spaceID, transferToOrg)
+}
+
 func (m *recoveringMiddleware) Update(ctx context.Context, space *spaces.Space) (err error) {
 	logger := m.logger
 	defer func() {
diff --git a/pkg/spaces/middleware/telemetry_middleware.go b/pkg/spaces/middleware/telemetry_middleware.go
index 2ef9f21e..4bbef080 100644
--- a/pkg/spaces/middleware/telemetry_middleware.go
+++ b/pkg/spaces/middleware/telemetry_middleware.go
@@ -1,9 +1,9 @@
+package middleware
+
 // Code generated by gowrap. DO NOT EDIT.
 // template: ../../../assets/templates/middleware/telemetry
 // gowrap: http://github.com/hexdigest/gowrap
 
-package middleware
-
 //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/spaces -i Spaces -t ../../../assets/templates/middleware/telemetry -o telemetry_middleware.go -l ""
 
 import (
@@ -36,6 +36,46 @@ func TelemetryMiddleware(base spaces.Spaces, instance string, spanDecorator ...f
 	return d
 }
 
+// AbortTransfer implements spaces.Spaces
+func (_d telemetryMiddleware) AbortTransfer(ctx context.Context, spaceID string) (err error) {
+	ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.AbortTransfer")
+	defer func() {
+		if _d._spanDecorator != nil {
+			_d._spanDecorator(_span, map[string]interface{}{
+				"ctx":     ctx,
+				"spaceID": spaceID}, map[string]interface{}{
+				"err": err})
+		} else if err != nil {
+			_span.RecordError(err)
+			_span.SetAttributes(attribute.String("event", "error"))
+			_span.SetAttributes(attribute.String("message", err.Error()))
+		}
+
+		_span.End()
+	}()
+	return _d.Spaces.AbortTransfer(ctx, spaceID)
+}
+
+// AcceptTransfer implements spaces.Spaces
+func (_d telemetryMiddleware) AcceptTransfer(ctx context.Context, spaceID string) (err error) {
+	ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.AcceptTransfer")
+	defer func() {
+		if _d._spanDecorator != nil {
+			_d._spanDecorator(_span, map[string]interface{}{
+				"ctx":     ctx,
+				"spaceID": spaceID}, map[string]interface{}{
+				"err": err})
+		} else if err != nil {
+			_span.RecordError(err)
+			_span.SetAttributes(attribute.String("event", "error"))
+			_span.SetAttributes(attribute.String("message", err.Error()))
+		}
+
+		_span.End()
+	}()
+	return _d.Spaces.AcceptTransfer(ctx, spaceID)
+}
+
 // Create implements spaces.Spaces
 func (_d telemetryMiddleware) Create(ctx context.Context, space *spaces.Space) (created *spaces.Space, err error) {
 	ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.Create")
@@ -119,6 +159,48 @@ func (_d telemetryMiddleware) List(ctx context.Context, orgId string) (spaces []
 	return _d.Spaces.List(ctx, orgId)
 }
 
+// ListTransfers implements spaces.Spaces
+func (_d telemetryMiddleware) ListTransfers(ctx context.Context, orgID string) (spaces []*spaces.Space, err error) {
+	ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.ListTransfers")
+	defer func() {
+		if _d._spanDecorator != nil {
+			_d._spanDecorator(_span, map[string]interface{}{
+				"ctx":   ctx,
+				"orgID": orgID}, map[string]interface{}{
+				"spaces": spaces,
+				"err":    err})
+		} else if err != nil {
+			_span.RecordError(err)
+			_span.SetAttributes(attribute.String("event", "error"))
+			_span.SetAttributes(attribute.String("message", err.Error()))
+		}
+
+		_span.End()
+	}()
+	return _d.Spaces.ListTransfers(ctx, orgID)
+}
+
+// Transfer implements spaces.Spaces
+func (_d telemetryMiddleware) Transfer(ctx context.Context, spaceID string, transferToOrg string) (err error) {
+	ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.Transfer")
+	defer func() {
+		if _d._spanDecorator != nil {
+			_d._spanDecorator(_span, map[string]interface{}{
+				"ctx":           ctx,
+				"spaceID":       spaceID,
+				"transferToOrg": transferToOrg}, map[string]interface{}{
+				"err": err})
+		} else if err != nil {
+			_span.RecordError(err)
+			_span.SetAttributes(attribute.String("event", "error"))
+			_span.SetAttributes(attribute.String("message", err.Error()))
+		}
+
+		_span.End()
+	}()
+	return _d.Spaces.Transfer(ctx, spaceID, transferToOrg)
+}
+
 // Update implements spaces.Spaces
 func (_d telemetryMiddleware) Update(ctx context.Context, space *spaces.Space) (err error) {
 	ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.Update")
diff --git a/pkg/spaces/mocks/Spaces.go b/pkg/spaces/mocks/Spaces.go
index c052825a..a7a7f39b 100644
--- a/pkg/spaces/mocks/Spaces.go
+++ b/pkg/spaces/mocks/Spaces.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.15.0. DO NOT EDIT.
+// Code generated by mockery v2.27.1. DO NOT EDIT.
 
 package mocks
 
@@ -14,11 +14,43 @@ type Spaces struct {
 	mock.Mock
 }
 
+// AbortTransfer provides a mock function with given fields: ctx, spaceID
+func (_m *Spaces) AbortTransfer(ctx context.Context, spaceID string) error {
+	ret := _m.Called(ctx, spaceID)
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
+		r0 = rf(ctx, spaceID)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// AcceptTransfer provides a mock function with given fields: ctx, spaceID
+func (_m *Spaces) AcceptTransfer(ctx context.Context, spaceID string) error {
+	ret := _m.Called(ctx, spaceID)
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
+		r0 = rf(ctx, spaceID)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
 // Create provides a mock function with given fields: ctx, space
 func (_m *Spaces) Create(ctx context.Context, space *spaces.Space) (*spaces.Space, error) {
 	ret := _m.Called(ctx, space)
 
 	var r0 *spaces.Space
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *spaces.Space) (*spaces.Space, error)); ok {
+		return rf(ctx, space)
+	}
 	if rf, ok := ret.Get(0).(func(context.Context, *spaces.Space) *spaces.Space); ok {
 		r0 = rf(ctx, space)
 	} else {
@@ -27,7 +59,6 @@ func (_m *Spaces) Create(ctx context.Context, space *spaces.Space) (*spaces.Spac
 		}
 	}
 
-	var r1 error
 	if rf, ok := ret.Get(1).(func(context.Context, *spaces.Space) error); ok {
 		r1 = rf(ctx, space)
 	} else {
@@ -56,6 +87,10 @@ func (_m *Spaces) Get(ctx context.Context, spaceId string) (*spaces.Space, error
 	ret := _m.Called(ctx, spaceId)
 
 	var r0 *spaces.Space
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, string) (*spaces.Space, error)); ok {
+		return rf(ctx, spaceId)
+	}
 	if rf, ok := ret.Get(0).(func(context.Context, string) *spaces.Space); ok {
 		r0 = rf(ctx, spaceId)
 	} else {
@@ -64,7 +99,6 @@ func (_m *Spaces) Get(ctx context.Context, spaceId string) (*spaces.Space, error
 		}
 	}
 
-	var r1 error
 	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
 		r1 = rf(ctx, spaceId)
 	} else {
@@ -79,6 +113,10 @@ func (_m *Spaces) List(ctx context.Context, orgId string) ([]*spaces.Space, erro
 	ret := _m.Called(ctx, orgId)
 
 	var r0 []*spaces.Space
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, string) ([]*spaces.Space, error)); ok {
+		return rf(ctx, orgId)
+	}
 	if rf, ok := ret.Get(0).(func(context.Context, string) []*spaces.Space); ok {
 		r0 = rf(ctx, orgId)
 	} else {
@@ -87,7 +125,6 @@ func (_m *Spaces) List(ctx context.Context, orgId string) ([]*spaces.Space, erro
 		}
 	}
 
-	var r1 error
 	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
 		r1 = rf(ctx, orgId)
 	} else {
@@ -97,6 +134,46 @@ func (_m *Spaces) List(ctx context.Context, orgId string) ([]*spaces.Space, erro
 	return r0, r1
 }
 
+// ListTransfers provides a mock function with given fields: ctx, orgID
+func (_m *Spaces) ListTransfers(ctx context.Context, orgID string) ([]*spaces.Space, error) {
+	ret := _m.Called(ctx, orgID)
+
+	var r0 []*spaces.Space
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, string) ([]*spaces.Space, error)); ok {
+		return rf(ctx, orgID)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, string) []*spaces.Space); ok {
+		r0 = rf(ctx, orgID)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]*spaces.Space)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
+		r1 = rf(ctx, orgID)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Transfer provides a mock function with given fields: ctx, spaceID, transferToOrg
+func (_m *Spaces) Transfer(ctx context.Context, spaceID string, transferToOrg string) error {
+	ret := _m.Called(ctx, spaceID, transferToOrg)
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok {
+		r0 = rf(ctx, spaceID, transferToOrg)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
 // Update provides a mock function with given fields: ctx, space
 func (_m *Spaces) Update(ctx context.Context, space *spaces.Space) error {
 	ret := _m.Called(ctx, space)
diff --git a/pkg/spaces/mocks/Storage.go b/pkg/spaces/mocks/Storage.go
index 5223c772..0f61e8c4 100644
--- a/pkg/spaces/mocks/Storage.go
+++ b/pkg/spaces/mocks/Storage.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.15.0. DO NOT EDIT.
+// Code generated by mockery v2.27.1. DO NOT EDIT.
 
 package mocks
 
@@ -35,13 +35,16 @@ func (_m *Storage) Delete(ctx context.Context, filter *spaces.Filter) (int, erro
 	ret := _m.Called(ctx, filter)
 
 	var r0 int
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *spaces.Filter) (int, error)); ok {
+		return rf(ctx, filter)
+	}
 	if rf, ok := ret.Get(0).(func(context.Context, *spaces.Filter) int); ok {
 		r0 = rf(ctx, filter)
 	} else {
 		r0 = ret.Get(0).(int)
 	}
 
-	var r1 error
 	if rf, ok := ret.Get(1).(func(context.Context, *spaces.Filter) error); ok {
 		r1 = rf(ctx, filter)
 	} else {
@@ -56,6 +59,11 @@ func (_m *Storage) Find(ctx context.Context, filter *spaces.Filter, opts *option
 	ret := _m.Called(ctx, filter, opts)
 
 	var r0 []*spaces.Space
+	var r1 int
+	var r2 error
+	if rf, ok := ret.Get(0).(func(context.Context, *spaces.Filter, *options.FindOptions) ([]*spaces.Space, int, error)); ok {
+		return rf(ctx, filter, opts)
+	}
 	if rf, ok := ret.Get(0).(func(context.Context, *spaces.Filter, *options.FindOptions) []*spaces.Space); ok {
 		r0 = rf(ctx, filter, opts)
 	} else {
@@ -64,14 +72,12 @@ func (_m *Storage) Find(ctx context.Context, filter *spaces.Filter, opts *option
 		}
 	}
 
-	var r1 int
 	if rf, ok := ret.Get(1).(func(context.Context, *spaces.Filter, *options.FindOptions) int); ok {
 		r1 = rf(ctx, filter, opts)
 	} else {
 		r1 = ret.Get(1).(int)
 	}
 
-	var r2 error
 	if rf, ok := ret.Get(2).(func(context.Context, *spaces.Filter, *options.FindOptions) error); ok {
 		r2 = rf(ctx, filter, opts)
 	} else {
@@ -114,20 +120,23 @@ func (_m *Storage) Update(ctx context.Context, update *spaces.Space, filter *spa
 	ret := _m.Called(ctx, update, filter)
 
 	var r0 int
+	var r1 int
+	var r2 error
+	if rf, ok := ret.Get(0).(func(context.Context, *spaces.Space, *spaces.Filter) (int, int, error)); ok {
+		return rf(ctx, update, filter)
+	}
 	if rf, ok := ret.Get(0).(func(context.Context, *spaces.Space, *spaces.Filter) int); ok {
 		r0 = rf(ctx, update, filter)
 	} else {
 		r0 = ret.Get(0).(int)
 	}
 
-	var r1 int
 	if rf, ok := ret.Get(1).(func(context.Context, *spaces.Space, *spaces.Filter) int); ok {
 		r1 = rf(ctx, update, filter)
 	} else {
 		r1 = ret.Get(1).(int)
 	}
 
-	var r2 error
 	if rf, ok := ret.Get(2).(func(context.Context, *spaces.Space, *spaces.Filter) error); ok {
 		r2 = rf(ctx, update, filter)
 	} else {
diff --git a/pkg/spaces/service.go b/pkg/spaces/service.go
index d31cbfeb..333d9d4a 100644
--- a/pkg/spaces/service.go
+++ b/pkg/spaces/service.go
@@ -27,6 +27,23 @@ type Spaces interface {
 	Update(ctx context.Context, space *Space) (err error)
 	UpdateConfig(ctx context.Context, spaceId string, config *Config) (err error)
 	Delete(ctx context.Context, spaceId string) (err error)
+
+	// Transfer устанавливает для пространства значение поля RequestedMoveTo. После этого пространство
+	// будет отображаться в списке входящих запросов на перемещение в организации `orgID` (запрос ListIncoming)
+	// С пространством можно продолжать работу в текущей организации, пока запрос на перемещение не будет
+	// принят в целевой организации
+	Transfer(ctx context.Context, spaceID, transferToOrg string) (err error)
+
+	// AbortTransfer - отменить перемещение пространства в другую организацию
+	AbortTransfer(ctx context.Context, spaceID string) (err error)
+
+	// ListTransfers возвращает список пространств, перемещение которых было запрошено в текущую организацию
+	ListTransfers(ctx context.Context, orgID string) (spaces []*Space, err error)
+
+	// AcceptTransfer - принять запрос на перемещение пространства. Оно будет перемещено в текущую организацию со
+	// всеми входящими в него данными: ролями, участниками, контентом, пр. и более не будет доступно в
+	// старой организации
+	AcceptTransfer(ctx context.Context, spaceID string) (err error)
 }
 
 func IsSpaceAvailable(ctx context.Context, spcs Spaces, spaceId string) error {
diff --git a/pkg/spaces/space.go b/pkg/spaces/space.go
index 772caa9c..b0aff6a4 100644
--- a/pkg/spaces/space.go
+++ b/pkg/spaces/space.go
@@ -20,13 +20,17 @@ type Config struct {
 const StateInfoEmpty = "EMPTY"
 
 type Space struct {
-	ID          string  `json:"id,omitempty" bson:"_id"`
-	OrgID       string  `json:"org_id,omitempty" bson:"org_id"`
-	Name        string  `json:"name,omitempty" bson:"name"`
-	Description string  `json:"desc,omitempty" bson:"desc"`
-	State       State   `json:"state" bson:"state"`
-	StateInfo   string  `json:"stateInfo,omitempty" bson:"stateInfo,omitempty"`
-	Config      *Config `json:"config" bson:"config"`
+	ID          string `json:"id,omitempty" bson:"_id"`
+	OrgID       string `json:"org_id,omitempty" bson:"org_id"`
+	Name        string `json:"name,omitempty" bson:"name"`
+	Description string `json:"desc,omitempty" bson:"desc"`
+	State       State  `json:"state" bson:"state"`
+	StateInfo   string `json:"stateInfo,omitempty" bson:"stateInfo,omitempty"`
+
+	// TransferToOrg - идентификатор организации, в которую был запрошен перенос пространства
+	TransferToOrg string `json:"transfer_to_org" bson:"transfer_to_org"`
+
+	Config *Config `json:"config" bson:"config"`
 }
 
 func (s Space) Clone() *Space {
diff --git a/pkg/spaces/storage.go b/pkg/spaces/storage.go
index 52baf9da..798dd96b 100644
--- a/pkg/spaces/storage.go
+++ b/pkg/spaces/storage.go
@@ -16,8 +16,9 @@ type Storage interface {
 }
 
 type Filter struct {
-	ID    []string `json:"id,omitempty" bson:"_id"`
-	OrgID []string `json:"org_id,omitempty" bson:"orgId"`
-	Name  []string `json:"name,omitempty" bson:"name"`
-	State []State  `json:"state,omitempty" bson:"state"`
+	ID            []string `json:"id,omitempty" bson:"_id"`
+	OrgID         []string `json:"org_id,omitempty" bson:"orgId"`
+	Name          []string `json:"name,omitempty" bson:"name"`
+	State         []State  `json:"state,omitempty" bson:"state"`
+	TransferToOrg []string `json:"transfer_to_org" bson:"transfer_to_org"`
 }
diff --git a/pkg/spaces/transport/client.go b/pkg/spaces/transport/client.go
index 4f13271e..6e94e0f2 100644
--- a/pkg/spaces/transport/client.go
+++ b/pkg/spaces/transport/client.go
@@ -64,3 +64,42 @@ func (set EndpointsSet) Delete(arg0 context.Context, arg1 string) (res0 error) {
 	}
 	return res0
 }
+
+func (set EndpointsSet) Transfer(arg0 context.Context, arg1 string, arg2 string) (res0 error) {
+	request := TransferRequest{
+		SpaceID:       arg1,
+		TransferToOrg: arg2,
+	}
+	_, res0 = set.TransferEndpoint(arg0, &request)
+	if res0 != nil {
+		return
+	}
+	return res0
+}
+
+func (set EndpointsSet) AbortTransfer(arg0 context.Context, arg1 string) (res0 error) {
+	request := AbortTransferRequest{SpaceID: arg1}
+	_, res0 = set.AbortTransferEndpoint(arg0, &request)
+	if res0 != nil {
+		return
+	}
+	return res0
+}
+
+func (set EndpointsSet) ListTransfers(arg0 context.Context, arg1 string) (res0 []*spaces.Space, res1 error) {
+	request := ListTransfersRequest{OrgID: arg1}
+	response, res1 := set.ListTransfersEndpoint(arg0, &request)
+	if res1 != nil {
+		return
+	}
+	return response.(*ListTransfersResponse).Spaces, res1
+}
+
+func (set EndpointsSet) AcceptTransfer(arg0 context.Context, arg1 string) (res0 error) {
+	request := AcceptTransferRequest{SpaceID: arg1}
+	_, res0 = set.AcceptTransferEndpoint(arg0, &request)
+	if res0 != nil {
+		return
+	}
+	return res0
+}
diff --git a/pkg/spaces/transport/endpoints.microgen.go b/pkg/spaces/transport/endpoints.microgen.go
index fae8a92d..6b4f07c1 100644
--- a/pkg/spaces/transport/endpoints.microgen.go
+++ b/pkg/spaces/transport/endpoints.microgen.go
@@ -6,10 +6,14 @@ import endpoint "github.com/go-kit/kit/endpoint"
 
 // EndpointsSet implements Spaces API and used for transport purposes.
 type EndpointsSet struct {
-	CreateEndpoint       endpoint.Endpoint
-	GetEndpoint          endpoint.Endpoint
-	ListEndpoint         endpoint.Endpoint
-	UpdateEndpoint       endpoint.Endpoint
-	UpdateConfigEndpoint endpoint.Endpoint
-	DeleteEndpoint       endpoint.Endpoint
+	CreateEndpoint         endpoint.Endpoint
+	GetEndpoint            endpoint.Endpoint
+	ListEndpoint           endpoint.Endpoint
+	UpdateEndpoint         endpoint.Endpoint
+	UpdateConfigEndpoint   endpoint.Endpoint
+	DeleteEndpoint         endpoint.Endpoint
+	TransferEndpoint       endpoint.Endpoint
+	AbortTransferEndpoint  endpoint.Endpoint
+	ListTransfersEndpoint  endpoint.Endpoint
+	AcceptTransferEndpoint endpoint.Endpoint
 }
diff --git a/pkg/spaces/transport/exchanges.microgen.go b/pkg/spaces/transport/exchanges.microgen.go
index 106753c6..7add10e4 100644
--- a/pkg/spaces/transport/exchanges.microgen.go
+++ b/pkg/spaces/transport/exchanges.microgen.go
@@ -44,4 +44,30 @@ type (
 	}
 	// Formal exchange type, please do not delete.
 	DeleteResponse struct{}
+
+	TransferRequest struct {
+		SpaceID       string `json:"space_id"`
+		TransferToOrg string `json:"transfer_to_org"`
+	}
+	// Formal exchange type, please do not delete.
+	TransferResponse struct{}
+
+	AbortTransferRequest struct {
+		SpaceID string `json:"space_id"`
+	}
+	// Formal exchange type, please do not delete.
+	AbortTransferResponse struct{}
+
+	ListTransfersRequest struct {
+		OrgID string `json:"org_id"`
+	}
+	ListTransfersResponse struct {
+		Spaces []*spaces.Space `json:"spaces"`
+	}
+
+	AcceptTransferRequest struct {
+		SpaceID string `json:"space_id"`
+	}
+	// Formal exchange type, please do not delete.
+	AcceptTransferResponse struct{}
 )
diff --git a/pkg/spaces/transport/grpc/client.go b/pkg/spaces/transport/grpc/client.go
index 693011ce..38865807 100644
--- a/pkg/spaces/transport/grpc/client.go
+++ b/pkg/spaces/transport/grpc/client.go
@@ -12,10 +12,15 @@ import (
 func NewClient(conn *grpc.ClientConn, opts ...grpckit.ClientOption) transport.EndpointsSet {
 	c := NewGRPCClient(conn, "", opts...)
 	return transport.EndpointsSet{
-		CreateEndpoint:       grpcerr.ClientMiddleware(c.CreateEndpoint),
-		GetEndpoint:          grpcerr.ClientMiddleware(c.GetEndpoint),
-		ListEndpoint:         grpcerr.ClientMiddleware(c.ListEndpoint),
-		UpdateEndpoint:       grpcerr.ClientMiddleware(c.UpdateEndpoint),
-		UpdateConfigEndpoint: grpcerr.ClientMiddleware(c.UpdateConfigEndpoint),
-		DeleteEndpoint:       grpcerr.ClientMiddleware(c.DeleteEndpoint)}
+		CreateEndpoint:         grpcerr.ClientMiddleware(c.CreateEndpoint),
+		GetEndpoint:            grpcerr.ClientMiddleware(c.GetEndpoint),
+		ListEndpoint:           grpcerr.ClientMiddleware(c.ListEndpoint),
+		UpdateEndpoint:         grpcerr.ClientMiddleware(c.UpdateEndpoint),
+		UpdateConfigEndpoint:   grpcerr.ClientMiddleware(c.UpdateConfigEndpoint),
+		DeleteEndpoint:         grpcerr.ClientMiddleware(c.DeleteEndpoint),
+		TransferEndpoint:       grpcerr.ClientMiddleware(c.TransferEndpoint),
+		AcceptTransferEndpoint: grpcerr.ClientMiddleware(c.AcceptTransferEndpoint),
+		ListTransfersEndpoint:  grpcerr.ClientMiddleware(c.ListTransfersEndpoint),
+		AbortTransferEndpoint:  grpcerr.ClientMiddleware(c.AbortTransferEndpoint),
+	}
 }
diff --git a/pkg/spaces/transport/grpc/client.microgen.go b/pkg/spaces/transport/grpc/client.microgen.go
index d6547f84..70ae5e24 100644
--- a/pkg/spaces/transport/grpc/client.microgen.go
+++ b/pkg/spaces/transport/grpc/client.microgen.go
@@ -15,6 +15,20 @@ func NewGRPCClient(conn *grpc.ClientConn, addr string, opts ...grpckit.ClientOpt
 		addr = "content.spaces.Spaces"
 	}
 	return transport.EndpointsSet{
+		AbortTransferEndpoint: grpckit.NewClient(
+			conn, addr, "AbortTransfer",
+			_Encode_AbortTransfer_Request,
+			_Decode_AbortTransfer_Response,
+			empty.Empty{},
+			opts...,
+		).Endpoint(),
+		AcceptTransferEndpoint: grpckit.NewClient(
+			conn, addr, "AcceptTransfer",
+			_Encode_AcceptTransfer_Request,
+			_Decode_AcceptTransfer_Response,
+			empty.Empty{},
+			opts...,
+		).Endpoint(),
 		CreateEndpoint: grpckit.NewClient(
 			conn, addr, "Create",
 			_Encode_Create_Request,
@@ -43,6 +57,20 @@ func NewGRPCClient(conn *grpc.ClientConn, addr string, opts ...grpckit.ClientOpt
 			pb.ListResponse{},
 			opts...,
 		).Endpoint(),
+		ListTransfersEndpoint: grpckit.NewClient(
+			conn, addr, "ListTransfers",
+			_Encode_ListTransfers_Request,
+			_Decode_ListTransfers_Response,
+			pb.ListTransfersResponse{},
+			opts...,
+		).Endpoint(),
+		TransferEndpoint: grpckit.NewClient(
+			conn, addr, "Transfer",
+			_Encode_Transfer_Request,
+			_Decode_Transfer_Response,
+			empty.Empty{},
+			opts...,
+		).Endpoint(),
 		UpdateConfigEndpoint: grpckit.NewClient(
 			conn, addr, "UpdateConfig",
 			_Encode_UpdateConfig_Request,
diff --git a/pkg/spaces/transport/grpc/protobuf_endpoint_converters.microgen.go b/pkg/spaces/transport/grpc/protobuf_endpoint_converters.microgen.go
index 3ea51a2a..99d269a4 100644
--- a/pkg/spaces/transport/grpc/protobuf_endpoint_converters.microgen.go
+++ b/pkg/spaces/transport/grpc/protobuf_endpoint_converters.microgen.go
@@ -233,3 +233,121 @@ func _Decode_UpdateConfig_Response(ctx context.Context, response interface{}) (i
 func _Decode_Delete_Response(ctx context.Context, response interface{}) (interface{}, error) {
 	return &empty.Empty{}, nil
 }
+
+func _Encode_Transfer_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil TransferRequest")
+	}
+	req := request.(*transport.TransferRequest)
+	return &pb.TransferRequest{
+		SpaceId:       req.SpaceID,
+		TransferToOrg: req.TransferToOrg,
+	}, nil
+}
+
+func _Encode_AbortTransfer_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil AbortTransferRequest")
+	}
+	req := request.(*transport.AbortTransferRequest)
+	return &pb.AbortTransferRequest{SpaceId: req.SpaceID}, nil
+}
+
+func _Encode_ListTransfers_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil ListTransfersRequest")
+	}
+	req := request.(*transport.ListTransfersRequest)
+	return &pb.ListTransfersRequest{OrgId: req.OrgID}, nil
+}
+
+func _Encode_AcceptTransfer_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil AcceptTransferRequest")
+	}
+	req := request.(*transport.AcceptTransferRequest)
+	return &pb.AcceptTransferRequest{SpaceId: req.SpaceID}, nil
+}
+
+func _Encode_Transfer_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	return &empty.Empty{}, nil
+}
+
+func _Encode_AbortTransfer_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	return &empty.Empty{}, nil
+}
+
+func _Encode_ListTransfers_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	if response == nil {
+		return nil, errors.New("nil ListTransfersResponse")
+	}
+	resp := response.(*transport.ListTransfersResponse)
+	respSpaces, err := ListPtrSpaceToProto(resp.Spaces)
+	if err != nil {
+		return nil, err
+	}
+	return &pb.ListTransfersResponse{Spaces: respSpaces}, nil
+}
+
+func _Encode_AcceptTransfer_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	return &empty.Empty{}, nil
+}
+
+func _Decode_Transfer_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil TransferRequest")
+	}
+	req := request.(*pb.TransferRequest)
+	return &transport.TransferRequest{
+		SpaceID:       string(req.SpaceId),
+		TransferToOrg: string(req.TransferToOrg),
+	}, nil
+}
+
+func _Decode_AbortTransfer_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil AbortTransferRequest")
+	}
+	req := request.(*pb.AbortTransferRequest)
+	return &transport.AbortTransferRequest{SpaceID: string(req.SpaceId)}, nil
+}
+
+func _Decode_ListTransfers_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil ListTransfersRequest")
+	}
+	req := request.(*pb.ListTransfersRequest)
+	return &transport.ListTransfersRequest{OrgID: string(req.OrgId)}, nil
+}
+
+func _Decode_AcceptTransfer_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil AcceptTransferRequest")
+	}
+	req := request.(*pb.AcceptTransferRequest)
+	return &transport.AcceptTransferRequest{SpaceID: string(req.SpaceId)}, nil
+}
+
+func _Decode_Transfer_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	return &empty.Empty{}, nil
+}
+
+func _Decode_AbortTransfer_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	return &empty.Empty{}, nil
+}
+
+func _Decode_ListTransfers_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	if response == nil {
+		return nil, errors.New("nil ListTransfersResponse")
+	}
+	resp := response.(*pb.ListTransfersResponse)
+	respSpaces, err := ProtoToListPtrSpace(resp.Spaces)
+	if err != nil {
+		return nil, err
+	}
+	return &transport.ListTransfersResponse{Spaces: respSpaces}, nil
+}
+
+func _Decode_AcceptTransfer_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	return &empty.Empty{}, nil
+}
diff --git a/pkg/spaces/transport/grpc/server.go b/pkg/spaces/transport/grpc/server.go
index bd38b0b9..8b4581a1 100644
--- a/pkg/spaces/transport/grpc/server.go
+++ b/pkg/spaces/transport/grpc/server.go
@@ -11,12 +11,16 @@ import (
 func NewServer(svc spaces.Spaces, opts ...grpckit.ServerOption) pb.SpacesServer {
 	eps := transport.Endpoints(svc)
 	eps = transport.EndpointsSet{
-		CreateEndpoint:       grpcerr.ServerMiddleware(eps.CreateEndpoint),
-		GetEndpoint:          grpcerr.ServerMiddleware(eps.GetEndpoint),
-		ListEndpoint:         grpcerr.ServerMiddleware(eps.ListEndpoint),
-		UpdateEndpoint:       grpcerr.ServerMiddleware(eps.UpdateEndpoint),
-		UpdateConfigEndpoint: grpcerr.ServerMiddleware(eps.UpdateConfigEndpoint),
-		DeleteEndpoint:       grpcerr.ServerMiddleware(eps.DeleteEndpoint),
+		CreateEndpoint:         grpcerr.ServerMiddleware(eps.CreateEndpoint),
+		GetEndpoint:            grpcerr.ServerMiddleware(eps.GetEndpoint),
+		ListEndpoint:           grpcerr.ServerMiddleware(eps.ListEndpoint),
+		UpdateEndpoint:         grpcerr.ServerMiddleware(eps.UpdateEndpoint),
+		UpdateConfigEndpoint:   grpcerr.ServerMiddleware(eps.UpdateConfigEndpoint),
+		DeleteEndpoint:         grpcerr.ServerMiddleware(eps.DeleteEndpoint),
+		TransferEndpoint:       grpcerr.ServerMiddleware(eps.TransferEndpoint),
+		AbortTransferEndpoint:  grpcerr.ServerMiddleware(eps.AbortTransferEndpoint),
+		AcceptTransferEndpoint: grpcerr.ServerMiddleware(eps.AcceptTransferEndpoint),
+		ListTransfersEndpoint:  grpcerr.ServerMiddleware(eps.ListTransfersEndpoint),
 	}
 	return NewGRPCServer(&eps, opts...)
 }
diff --git a/pkg/spaces/transport/grpc/server.microgen.go b/pkg/spaces/transport/grpc/server.microgen.go
index 437b8ad3..dcb08b51 100644
--- a/pkg/spaces/transport/grpc/server.microgen.go
+++ b/pkg/spaces/transport/grpc/server.microgen.go
@@ -12,18 +12,34 @@ import (
 )
 
 type spacesServer struct {
-	create       grpc.Handler
-	get          grpc.Handler
-	list         grpc.Handler
-	update       grpc.Handler
-	updateConfig grpc.Handler
-	delete       grpc.Handler
+	create         grpc.Handler
+	get            grpc.Handler
+	list           grpc.Handler
+	update         grpc.Handler
+	updateConfig   grpc.Handler
+	delete         grpc.Handler
+	transfer       grpc.Handler
+	abortTransfer  grpc.Handler
+	listTransfers  grpc.Handler
+	acceptTransfer grpc.Handler
 
 	pb.UnimplementedSpacesServer
 }
 
 func NewGRPCServer(endpoints *transport.EndpointsSet, opts ...grpc.ServerOption) pb.SpacesServer {
 	return &spacesServer{
+		abortTransfer: grpc.NewServer(
+			endpoints.AbortTransferEndpoint,
+			_Decode_AbortTransfer_Request,
+			_Encode_AbortTransfer_Response,
+			opts...,
+		),
+		acceptTransfer: grpc.NewServer(
+			endpoints.AcceptTransferEndpoint,
+			_Decode_AcceptTransfer_Request,
+			_Encode_AcceptTransfer_Response,
+			opts...,
+		),
 		create: grpc.NewServer(
 			endpoints.CreateEndpoint,
 			_Decode_Create_Request,
@@ -48,6 +64,18 @@ func NewGRPCServer(endpoints *transport.EndpointsSet, opts ...grpc.ServerOption)
 			_Encode_List_Response,
 			opts...,
 		),
+		listTransfers: grpc.NewServer(
+			endpoints.ListTransfersEndpoint,
+			_Decode_ListTransfers_Request,
+			_Encode_ListTransfers_Response,
+			opts...,
+		),
+		transfer: grpc.NewServer(
+			endpoints.TransferEndpoint,
+			_Decode_Transfer_Request,
+			_Encode_Transfer_Response,
+			opts...,
+		),
 		update: grpc.NewServer(
 			endpoints.UpdateEndpoint,
 			_Decode_Update_Request,
@@ -110,3 +138,35 @@ func (S *spacesServer) Delete(ctx context.Context, req *pb.DeleteRequest) (*empt
 	}
 	return resp.(*empty.Empty), nil
 }
+
+func (S *spacesServer) Transfer(ctx context.Context, req *pb.TransferRequest) (*empty.Empty, error) {
+	_, resp, err := S.transfer.ServeGRPC(ctx, req)
+	if err != nil {
+		return nil, err
+	}
+	return resp.(*empty.Empty), nil
+}
+
+func (S *spacesServer) AbortTransfer(ctx context.Context, req *pb.AbortTransferRequest) (*empty.Empty, error) {
+	_, resp, err := S.abortTransfer.ServeGRPC(ctx, req)
+	if err != nil {
+		return nil, err
+	}
+	return resp.(*empty.Empty), nil
+}
+
+func (S *spacesServer) ListTransfers(ctx context.Context, req *pb.ListTransfersRequest) (*pb.ListTransfersResponse, error) {
+	_, resp, err := S.listTransfers.ServeGRPC(ctx, req)
+	if err != nil {
+		return nil, err
+	}
+	return resp.(*pb.ListTransfersResponse), nil
+}
+
+func (S *spacesServer) AcceptTransfer(ctx context.Context, req *pb.AcceptTransferRequest) (*empty.Empty, error) {
+	_, resp, err := S.acceptTransfer.ServeGRPC(ctx, req)
+	if err != nil {
+		return nil, err
+	}
+	return resp.(*empty.Empty), nil
+}
diff --git a/pkg/spaces/transport/server.microgen.go b/pkg/spaces/transport/server.microgen.go
index 864dbffe..ef3cdc50 100644
--- a/pkg/spaces/transport/server.microgen.go
+++ b/pkg/spaces/transport/server.microgen.go
@@ -11,12 +11,16 @@ import (
 
 func Endpoints(svc spaces.Spaces) EndpointsSet {
 	return EndpointsSet{
-		CreateEndpoint:       CreateEndpoint(svc),
-		DeleteEndpoint:       DeleteEndpoint(svc),
-		GetEndpoint:          GetEndpoint(svc),
-		ListEndpoint:         ListEndpoint(svc),
-		UpdateConfigEndpoint: UpdateConfigEndpoint(svc),
-		UpdateEndpoint:       UpdateEndpoint(svc),
+		AbortTransferEndpoint:  AbortTransferEndpoint(svc),
+		AcceptTransferEndpoint: AcceptTransferEndpoint(svc),
+		CreateEndpoint:         CreateEndpoint(svc),
+		DeleteEndpoint:         DeleteEndpoint(svc),
+		GetEndpoint:            GetEndpoint(svc),
+		ListEndpoint:           ListEndpoint(svc),
+		ListTransfersEndpoint:  ListTransfersEndpoint(svc),
+		TransferEndpoint:       TransferEndpoint(svc),
+		UpdateConfigEndpoint:   UpdateConfigEndpoint(svc),
+		UpdateEndpoint:         UpdateEndpoint(svc),
 	}
 }
 
@@ -67,3 +71,35 @@ func DeleteEndpoint(svc spaces.Spaces) endpoint.Endpoint {
 		return &DeleteResponse{}, res0
 	}
 }
+
+func TransferEndpoint(svc spaces.Spaces) endpoint.Endpoint {
+	return func(arg0 context.Context, request interface{}) (interface{}, error) {
+		req := request.(*TransferRequest)
+		res0 := svc.Transfer(arg0, req.SpaceID, req.TransferToOrg)
+		return &TransferResponse{}, res0
+	}
+}
+
+func AbortTransferEndpoint(svc spaces.Spaces) endpoint.Endpoint {
+	return func(arg0 context.Context, request interface{}) (interface{}, error) {
+		req := request.(*AbortTransferRequest)
+		res0 := svc.AbortTransfer(arg0, req.SpaceID)
+		return &AbortTransferResponse{}, res0
+	}
+}
+
+func ListTransfersEndpoint(svc spaces.Spaces) endpoint.Endpoint {
+	return func(arg0 context.Context, request interface{}) (interface{}, error) {
+		req := request.(*ListTransfersRequest)
+		res0, res1 := svc.ListTransfers(arg0, req.OrgID)
+		return &ListTransfersResponse{Spaces: res0}, res1
+	}
+}
+
+func AcceptTransferEndpoint(svc spaces.Spaces) endpoint.Endpoint {
+	return func(arg0 context.Context, request interface{}) (interface{}, error) {
+		req := request.(*AcceptTransferRequest)
+		res0 := svc.AcceptTransfer(arg0, req.SpaceID)
+		return &AcceptTransferResponse{}, res0
+	}
+}
diff --git a/proto/spaces/spaces.pb.go b/proto/spaces/spaces.pb.go
index 3c3a8784..7fe57ee6 100644
--- a/proto/spaces/spaces.pb.go
+++ b/proto/spaces/spaces.pb.go
@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.29.0
+// 	protoc-gen-go v1.30.0
 // 	protoc        v3.21.12
 // source: spaces/spaces.proto
 
@@ -90,12 +90,13 @@ type Space struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Id          string  `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
-	OrgId       string  `protobuf:"bytes,2,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"`
-	Name        string  `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
-	Description string  `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"`
-	State       State   `protobuf:"varint,5,opt,name=state,proto3,enum=content.spaces.State" json:"state,omitempty"`
-	Config      *Config `protobuf:"bytes,10,opt,name=config,proto3" json:"config,omitempty"`
+	Id            string  `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
+	OrgId         string  `protobuf:"bytes,2,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"`
+	Name          string  `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
+	Description   string  `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"`
+	State         State   `protobuf:"varint,5,opt,name=state,proto3,enum=content.spaces.State" json:"state,omitempty"`
+	TransferToOrg string  `protobuf:"bytes,6,opt,name=transfer_to_org,json=transferToOrg,proto3" json:"transfer_to_org,omitempty"` // идентификатор организации, в которую запрошен перенос пространства
+	Config        *Config `protobuf:"bytes,10,opt,name=config,proto3" json:"config,omitempty"`
 }
 
 func (x *Space) Reset() {
@@ -165,6 +166,13 @@ func (x *Space) GetState() State {
 	return State_UNKNOWN
 }
 
+func (x *Space) GetTransferToOrg() string {
+	if x != nil {
+		return x.TransferToOrg
+	}
+	return ""
+}
+
 func (x *Space) GetConfig() *Config {
 	if x != nil {
 		return x.Config
@@ -650,6 +658,249 @@ func (x *DeleteRequest) GetSpaceId() string {
 	return ""
 }
 
+type TransferRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	SpaceId       string `protobuf:"bytes,1,opt,name=space_id,json=spaceId,proto3" json:"space_id,omitempty"`
+	TransferToOrg string `protobuf:"bytes,2,opt,name=transfer_to_org,json=transferToOrg,proto3" json:"transfer_to_org,omitempty"`
+}
+
+func (x *TransferRequest) Reset() {
+	*x = TransferRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_spaces_spaces_proto_msgTypes[11]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *TransferRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TransferRequest) ProtoMessage() {}
+
+func (x *TransferRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_spaces_spaces_proto_msgTypes[11]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use TransferRequest.ProtoReflect.Descriptor instead.
+func (*TransferRequest) Descriptor() ([]byte, []int) {
+	return file_spaces_spaces_proto_rawDescGZIP(), []int{11}
+}
+
+func (x *TransferRequest) GetSpaceId() string {
+	if x != nil {
+		return x.SpaceId
+	}
+	return ""
+}
+
+func (x *TransferRequest) GetTransferToOrg() string {
+	if x != nil {
+		return x.TransferToOrg
+	}
+	return ""
+}
+
+type AbortTransferRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	SpaceId string `protobuf:"bytes,1,opt,name=space_id,json=spaceId,proto3" json:"space_id,omitempty"`
+}
+
+func (x *AbortTransferRequest) Reset() {
+	*x = AbortTransferRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_spaces_spaces_proto_msgTypes[12]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AbortTransferRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AbortTransferRequest) ProtoMessage() {}
+
+func (x *AbortTransferRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_spaces_spaces_proto_msgTypes[12]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AbortTransferRequest.ProtoReflect.Descriptor instead.
+func (*AbortTransferRequest) Descriptor() ([]byte, []int) {
+	return file_spaces_spaces_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *AbortTransferRequest) GetSpaceId() string {
+	if x != nil {
+		return x.SpaceId
+	}
+	return ""
+}
+
+type ListTransfersRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	OrgId string `protobuf:"bytes,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"`
+}
+
+func (x *ListTransfersRequest) Reset() {
+	*x = ListTransfersRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_spaces_spaces_proto_msgTypes[13]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListTransfersRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListTransfersRequest) ProtoMessage() {}
+
+func (x *ListTransfersRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_spaces_spaces_proto_msgTypes[13]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListTransfersRequest.ProtoReflect.Descriptor instead.
+func (*ListTransfersRequest) Descriptor() ([]byte, []int) {
+	return file_spaces_spaces_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *ListTransfersRequest) GetOrgId() string {
+	if x != nil {
+		return x.OrgId
+	}
+	return ""
+}
+
+type ListTransfersResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Spaces []*Space `protobuf:"bytes,1,rep,name=spaces,proto3" json:"spaces,omitempty"`
+}
+
+func (x *ListTransfersResponse) Reset() {
+	*x = ListTransfersResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_spaces_spaces_proto_msgTypes[14]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListTransfersResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListTransfersResponse) ProtoMessage() {}
+
+func (x *ListTransfersResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_spaces_spaces_proto_msgTypes[14]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListTransfersResponse.ProtoReflect.Descriptor instead.
+func (*ListTransfersResponse) Descriptor() ([]byte, []int) {
+	return file_spaces_spaces_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *ListTransfersResponse) GetSpaces() []*Space {
+	if x != nil {
+		return x.Spaces
+	}
+	return nil
+}
+
+type AcceptTransferRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	SpaceId string `protobuf:"bytes,1,opt,name=space_id,json=spaceId,proto3" json:"space_id,omitempty"`
+}
+
+func (x *AcceptTransferRequest) Reset() {
+	*x = AcceptTransferRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_spaces_spaces_proto_msgTypes[15]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AcceptTransferRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AcceptTransferRequest) ProtoMessage() {}
+
+func (x *AcceptTransferRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_spaces_spaces_proto_msgTypes[15]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AcceptTransferRequest.ProtoReflect.Descriptor instead.
+func (*AcceptTransferRequest) Descriptor() ([]byte, []int) {
+	return file_spaces_spaces_proto_rawDescGZIP(), []int{15}
+}
+
+func (x *AcceptTransferRequest) GetSpaceId() string {
+	if x != nil {
+		return x.SpaceId
+	}
+	return ""
+}
+
 var File_spaces_spaces_proto protoreflect.FileDescriptor
 
 var file_spaces_spaces_proto_rawDesc = []byte{
@@ -657,7 +908,7 @@ var file_spaces_spaces_proto_rawDesc = []byte{
 	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73,
 	0x70, 0x61, 0x63, 0x65, 0x73, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
 	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x22, 0xc1, 0x01, 0x0a, 0x05, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02,
+	0x74, 0x6f, 0x22, 0xe9, 0x01, 0x0a, 0x05, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02,
 	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x15, 0x0a, 0x06,
 	0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72,
 	0x67, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
@@ -666,84 +917,126 @@ var file_spaces_spaces_proto_rawDesc = []byte{
 	0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, 0x61,
 	0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
 	0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52,
-	0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
-	0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06,
-	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x24, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x12, 0x1a, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,
-	0x28, 0x09, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x3c, 0x0a, 0x0d,
-	0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a,
-	0x05, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63,
-	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x70,
-	0x61, 0x63, 0x65, 0x52, 0x05, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x41, 0x0a, 0x0e, 0x43, 0x72,
-	0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07,
-	0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e,
-	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53,
-	0x70, 0x61, 0x63, 0x65, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x27, 0x0a,
-	0x0a, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73,
-	0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73,
-	0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x22, 0x3a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01,
+	0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66,
+	0x65, 0x72, 0x5f, 0x74, 0x6f, 0x5f, 0x6f, 0x72, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x6f, 0x4f, 0x72, 0x67, 0x12, 0x2e,
+	0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16,
+	0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x24,
+	0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74,
+	0x75, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74,
+	0x75, 0x72, 0x65, 0x73, 0x22, 0x3c, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01,
 	0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73,
 	0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x05, 0x73, 0x70, 0x61,
-	0x63, 0x65, 0x22, 0x24, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x22, 0x3d, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x06, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
-	0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52,
-	0x06, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x22, 0x3c, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74,
-	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
-	0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x05,
-	0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x60, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08,
-	0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
-	0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
-	0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
-	0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x2a, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74,
-	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x49, 0x64, 0x2a, 0x70, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07,
-	0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4e, 0x45, 0x57,
-	0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x02, 0x12, 0x0d, 0x0a,
-	0x09, 0x50, 0x52, 0x45, 0x50, 0x41, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b,
-	0x4d, 0x41, 0x49, 0x4e, 0x54, 0x45, 0x4e, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x04, 0x12, 0x0d, 0x0a,
-	0x09, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x0c, 0x0a, 0x08,
-	0x44, 0x45, 0x4c, 0x45, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x06, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52,
-	0x52, 0x4f, 0x52, 0x10, 0x07, 0x32, 0xaf, 0x03, 0x0a, 0x06, 0x53, 0x70, 0x61, 0x63, 0x65, 0x73,
-	0x12, 0x49, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x63, 0x6f, 0x6e,
-	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61,
-	0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
-	0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74,
-	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x03, 0x47,
-	0x65, 0x74, 0x12, 0x1a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61,
-	0x63, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b,
+	0x63, 0x65, 0x22, 0x41, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e,
+	0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x07, 0x63, 0x72,
+	0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x27, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x22, 0x3a,
+	0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a,
+	0x05, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63,
+	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x70,
+	0x61, 0x63, 0x65, 0x52, 0x05, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x24, 0x0a, 0x0b, 0x4c, 0x69,
+	0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67,
+	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64,
+	0x22, 0x3d, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x2d, 0x0a, 0x06, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65,
+	0x73, 0x2e, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x06, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x22,
+	0x3c, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x2b, 0x0a, 0x05, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73,
+	0x2e, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x05, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x60, 0x0a,
+	0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12,
+	0x2e, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x16, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73,
+	0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22,
+	0x2a, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x22, 0x54, 0x0a, 0x0f, 0x54,
+	0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19,
+	0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x72, 0x61,
+	0x6e, 0x73, 0x66, 0x65, 0x72, 0x5f, 0x74, 0x6f, 0x5f, 0x6f, 0x72, 0x67, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x6f, 0x4f, 0x72,
+	0x67, 0x22, 0x31, 0x0a, 0x14, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66,
+	0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61,
+	0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61,
+	0x63, 0x65, 0x49, 0x64, 0x22, 0x2d, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e,
+	0x73, 0x66, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06,
+	0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72,
+	0x67, 0x49, 0x64, 0x22, 0x46, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73,
+	0x66, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x06,
+	0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63,
+	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x70,
+	0x61, 0x63, 0x65, 0x52, 0x06, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x22, 0x32, 0x0a, 0x15, 0x41,
+	0x63, 0x63, 0x65, 0x70, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x2a,
+	0x70, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e,
+	0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4e, 0x45, 0x57, 0x10, 0x01, 0x12, 0x09,
+	0x0a, 0x05, 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x52, 0x45,
+	0x50, 0x41, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x41, 0x49, 0x4e,
+	0x54, 0x45, 0x4e, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x4d, 0x49, 0x47,
+	0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x45, 0x4c, 0x45,
+	0x54, 0x49, 0x4e, 0x47, 0x10, 0x06, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10,
+	0x07, 0x32, 0xfa, 0x05, 0x0a, 0x06, 0x53, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x49, 0x0a, 0x06,
+	0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
+	0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e,
+	0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x1a,
 	0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e,
-	0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a,
-	0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e,
-	0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61,
-	0x63, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x22, 0x00, 0x12, 0x41, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x63,
-	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x55, 0x70,
-	0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f,
-	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
-	0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e,
-	0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
-	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
-	0x74, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1d,
+	0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x63, 0x6f, 0x6e,
+	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x04, 0x4c, 0x69, 0x73,
+	0x74, 0x12, 0x1b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63,
+	0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c,
 	0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e,
-	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e,
-	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
-	0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x2e, 0x70,
-	0x65, 0x72, 0x78, 0x2e, 0x72, 0x75, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2f, 0x70, 0x65,
-	0x72, 0x78, 0x69, 0x73, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x70,
-	0x61, 0x63, 0x65, 0x73, 0x3b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x33,
+	0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41,
+	0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+	0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22,
+	0x00, 0x12, 0x4d, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x12, 0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63,
+	0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00,
+	0x12, 0x41, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x63, 0x6f, 0x6e,
+	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65,
+	0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
+	0x79, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x08, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12,
+	0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73,
+	0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+	0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0d, 0x41, 0x62,
+	0x6f, 0x72, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x24, 0x2e, 0x63, 0x6f,
+	0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x41, 0x62, 0x6f,
+	0x72, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x0d, 0x4c,
+	0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x24, 0x2e, 0x63,
+	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x4c, 0x69,
+	0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x25, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61,
+	0x63, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72,
+	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0e, 0x41,
+	0x63, 0x63, 0x65, 0x70, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x25, 0x2e,
+	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x41,
+	0x63, 0x63, 0x65, 0x70, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x32,
+	0x5a, 0x30, 0x67, 0x69, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x78, 0x2e, 0x72, 0x75, 0x2f, 0x70, 0x65,
+	0x72, 0x78, 0x69, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2d, 0x67, 0x6f, 0x2f, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x3b, 0x73, 0x70, 0x61, 0x63,
+	0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -759,21 +1052,26 @@ func file_spaces_spaces_proto_rawDescGZIP() []byte {
 }
 
 var file_spaces_spaces_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_spaces_spaces_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
+var file_spaces_spaces_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
 var file_spaces_spaces_proto_goTypes = []interface{}{
-	(State)(0),                  // 0: content.spaces.State
-	(*Space)(nil),               // 1: content.spaces.Space
-	(*Config)(nil),              // 2: content.spaces.Config
-	(*CreateRequest)(nil),       // 3: content.spaces.CreateRequest
-	(*CreateResponse)(nil),      // 4: content.spaces.CreateResponse
-	(*GetRequest)(nil),          // 5: content.spaces.GetRequest
-	(*GetResponse)(nil),         // 6: content.spaces.GetResponse
-	(*ListRequest)(nil),         // 7: content.spaces.ListRequest
-	(*ListResponse)(nil),        // 8: content.spaces.ListResponse
-	(*UpdateRequest)(nil),       // 9: content.spaces.UpdateRequest
-	(*UpdateConfigRequest)(nil), // 10: content.spaces.UpdateConfigRequest
-	(*DeleteRequest)(nil),       // 11: content.spaces.DeleteRequest
-	(*emptypb.Empty)(nil),       // 12: google.protobuf.Empty
+	(State)(0),                    // 0: content.spaces.State
+	(*Space)(nil),                 // 1: content.spaces.Space
+	(*Config)(nil),                // 2: content.spaces.Config
+	(*CreateRequest)(nil),         // 3: content.spaces.CreateRequest
+	(*CreateResponse)(nil),        // 4: content.spaces.CreateResponse
+	(*GetRequest)(nil),            // 5: content.spaces.GetRequest
+	(*GetResponse)(nil),           // 6: content.spaces.GetResponse
+	(*ListRequest)(nil),           // 7: content.spaces.ListRequest
+	(*ListResponse)(nil),          // 8: content.spaces.ListResponse
+	(*UpdateRequest)(nil),         // 9: content.spaces.UpdateRequest
+	(*UpdateConfigRequest)(nil),   // 10: content.spaces.UpdateConfigRequest
+	(*DeleteRequest)(nil),         // 11: content.spaces.DeleteRequest
+	(*TransferRequest)(nil),       // 12: content.spaces.TransferRequest
+	(*AbortTransferRequest)(nil),  // 13: content.spaces.AbortTransferRequest
+	(*ListTransfersRequest)(nil),  // 14: content.spaces.ListTransfersRequest
+	(*ListTransfersResponse)(nil), // 15: content.spaces.ListTransfersResponse
+	(*AcceptTransferRequest)(nil), // 16: content.spaces.AcceptTransferRequest
+	(*emptypb.Empty)(nil),         // 17: google.protobuf.Empty
 }
 var file_spaces_spaces_proto_depIdxs = []int32{
 	0,  // 0: content.spaces.Space.state:type_name -> content.spaces.State
@@ -784,23 +1082,32 @@ var file_spaces_spaces_proto_depIdxs = []int32{
 	1,  // 5: content.spaces.ListResponse.spaces:type_name -> content.spaces.Space
 	1,  // 6: content.spaces.UpdateRequest.space:type_name -> content.spaces.Space
 	2,  // 7: content.spaces.UpdateConfigRequest.config:type_name -> content.spaces.Config
-	3,  // 8: content.spaces.Spaces.Create:input_type -> content.spaces.CreateRequest
-	5,  // 9: content.spaces.Spaces.Get:input_type -> content.spaces.GetRequest
-	7,  // 10: content.spaces.Spaces.List:input_type -> content.spaces.ListRequest
-	9,  // 11: content.spaces.Spaces.Update:input_type -> content.spaces.UpdateRequest
-	10, // 12: content.spaces.Spaces.UpdateConfig:input_type -> content.spaces.UpdateConfigRequest
-	11, // 13: content.spaces.Spaces.Delete:input_type -> content.spaces.DeleteRequest
-	4,  // 14: content.spaces.Spaces.Create:output_type -> content.spaces.CreateResponse
-	6,  // 15: content.spaces.Spaces.Get:output_type -> content.spaces.GetResponse
-	8,  // 16: content.spaces.Spaces.List:output_type -> content.spaces.ListResponse
-	12, // 17: content.spaces.Spaces.Update:output_type -> google.protobuf.Empty
-	12, // 18: content.spaces.Spaces.UpdateConfig:output_type -> google.protobuf.Empty
-	12, // 19: content.spaces.Spaces.Delete:output_type -> google.protobuf.Empty
-	14, // [14:20] is the sub-list for method output_type
-	8,  // [8:14] is the sub-list for method input_type
-	8,  // [8:8] is the sub-list for extension type_name
-	8,  // [8:8] is the sub-list for extension extendee
-	0,  // [0:8] is the sub-list for field type_name
+	1,  // 8: content.spaces.ListTransfersResponse.spaces:type_name -> content.spaces.Space
+	3,  // 9: content.spaces.Spaces.Create:input_type -> content.spaces.CreateRequest
+	5,  // 10: content.spaces.Spaces.Get:input_type -> content.spaces.GetRequest
+	7,  // 11: content.spaces.Spaces.List:input_type -> content.spaces.ListRequest
+	9,  // 12: content.spaces.Spaces.Update:input_type -> content.spaces.UpdateRequest
+	10, // 13: content.spaces.Spaces.UpdateConfig:input_type -> content.spaces.UpdateConfigRequest
+	11, // 14: content.spaces.Spaces.Delete:input_type -> content.spaces.DeleteRequest
+	12, // 15: content.spaces.Spaces.Transfer:input_type -> content.spaces.TransferRequest
+	13, // 16: content.spaces.Spaces.AbortTransfer:input_type -> content.spaces.AbortTransferRequest
+	14, // 17: content.spaces.Spaces.ListTransfers:input_type -> content.spaces.ListTransfersRequest
+	16, // 18: content.spaces.Spaces.AcceptTransfer:input_type -> content.spaces.AcceptTransferRequest
+	4,  // 19: content.spaces.Spaces.Create:output_type -> content.spaces.CreateResponse
+	6,  // 20: content.spaces.Spaces.Get:output_type -> content.spaces.GetResponse
+	8,  // 21: content.spaces.Spaces.List:output_type -> content.spaces.ListResponse
+	17, // 22: content.spaces.Spaces.Update:output_type -> google.protobuf.Empty
+	17, // 23: content.spaces.Spaces.UpdateConfig:output_type -> google.protobuf.Empty
+	17, // 24: content.spaces.Spaces.Delete:output_type -> google.protobuf.Empty
+	17, // 25: content.spaces.Spaces.Transfer:output_type -> google.protobuf.Empty
+	17, // 26: content.spaces.Spaces.AbortTransfer:output_type -> google.protobuf.Empty
+	15, // 27: content.spaces.Spaces.ListTransfers:output_type -> content.spaces.ListTransfersResponse
+	17, // 28: content.spaces.Spaces.AcceptTransfer:output_type -> google.protobuf.Empty
+	19, // [19:29] is the sub-list for method output_type
+	9,  // [9:19] is the sub-list for method input_type
+	9,  // [9:9] is the sub-list for extension type_name
+	9,  // [9:9] is the sub-list for extension extendee
+	0,  // [0:9] is the sub-list for field type_name
 }
 
 func init() { file_spaces_spaces_proto_init() }
@@ -941,6 +1248,66 @@ func file_spaces_spaces_proto_init() {
 				return nil
 			}
 		}
+		file_spaces_spaces_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*TransferRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_spaces_spaces_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AbortTransferRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_spaces_spaces_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListTransfersRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_spaces_spaces_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListTransfersResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_spaces_spaces_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AcceptTransferRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -948,7 +1315,7 @@ func file_spaces_spaces_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_spaces_spaces_proto_rawDesc,
 			NumEnums:      1,
-			NumMessages:   11,
+			NumMessages:   16,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
diff --git a/proto/spaces/spaces_grpc.pb.go b/proto/spaces/spaces_grpc.pb.go
index 6dc461f5..89535627 100644
--- a/proto/spaces/spaces_grpc.pb.go
+++ b/proto/spaces/spaces_grpc.pb.go
@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
 // versions:
-// - protoc-gen-go-grpc v1.3.0
+// - protoc-gen-go-grpc v1.2.0
 // - protoc             v3.21.12
 // source: spaces/spaces.proto
 
@@ -19,15 +19,6 @@ import (
 // Requires gRPC-Go v1.32.0 or later.
 const _ = grpc.SupportPackageIsVersion7
 
-const (
-	Spaces_Create_FullMethodName       = "/content.spaces.Spaces/Create"
-	Spaces_Get_FullMethodName          = "/content.spaces.Spaces/Get"
-	Spaces_List_FullMethodName         = "/content.spaces.Spaces/List"
-	Spaces_Update_FullMethodName       = "/content.spaces.Spaces/Update"
-	Spaces_UpdateConfig_FullMethodName = "/content.spaces.Spaces/UpdateConfig"
-	Spaces_Delete_FullMethodName       = "/content.spaces.Spaces/Delete"
-)
-
 // SpacesClient is the client API for Spaces service.
 //
 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
@@ -38,6 +29,19 @@ type SpacesClient interface {
 	Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
 	UpdateConfig(ctx context.Context, in *UpdateConfigRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
 	Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
+	// Transfer устанавливает для пространства значение поля RequestedMoveTo. После этого пространство
+	// будет отображаться в списке входящих запросов на перемещение в организации `orgID` (запрос ListIncoming)
+	// С пространством можно продолжать работу в текущей организации, пока запрос на перемещение не будет
+	// принят в целевой организации
+	Transfer(ctx context.Context, in *TransferRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
+	// AbortTransfer - отменить перемещение пространства в другую организацию
+	AbortTransfer(ctx context.Context, in *AbortTransferRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
+	// ListTransfers возвращает список пространств, перемещение которых было запрошено в текущую организацию
+	ListTransfers(ctx context.Context, in *ListTransfersRequest, opts ...grpc.CallOption) (*ListTransfersResponse, error)
+	// AcceptTransfer - принять запрос на перемещение пространства. Оно будет перемещено в текущую организацию со
+	// всеми входящими в него данными: ролями, участниками, контентом, пр. и более не будет доступно в
+	// старой организации
+	AcceptTransfer(ctx context.Context, in *AcceptTransferRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
 }
 
 type spacesClient struct {
@@ -50,7 +54,7 @@ func NewSpacesClient(cc grpc.ClientConnInterface) SpacesClient {
 
 func (c *spacesClient) Create(ctx context.Context, in *CreateRequest, opts ...grpc.CallOption) (*CreateResponse, error) {
 	out := new(CreateResponse)
-	err := c.cc.Invoke(ctx, Spaces_Create_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/content.spaces.Spaces/Create", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -59,7 +63,7 @@ func (c *spacesClient) Create(ctx context.Context, in *CreateRequest, opts ...gr
 
 func (c *spacesClient) Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetResponse, error) {
 	out := new(GetResponse)
-	err := c.cc.Invoke(ctx, Spaces_Get_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/content.spaces.Spaces/Get", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -68,7 +72,7 @@ func (c *spacesClient) Get(ctx context.Context, in *GetRequest, opts ...grpc.Cal
 
 func (c *spacesClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) {
 	out := new(ListResponse)
-	err := c.cc.Invoke(ctx, Spaces_List_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/content.spaces.Spaces/List", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -77,7 +81,7 @@ func (c *spacesClient) List(ctx context.Context, in *ListRequest, opts ...grpc.C
 
 func (c *spacesClient) Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
 	out := new(emptypb.Empty)
-	err := c.cc.Invoke(ctx, Spaces_Update_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/content.spaces.Spaces/Update", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -86,7 +90,7 @@ func (c *spacesClient) Update(ctx context.Context, in *UpdateRequest, opts ...gr
 
 func (c *spacesClient) UpdateConfig(ctx context.Context, in *UpdateConfigRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
 	out := new(emptypb.Empty)
-	err := c.cc.Invoke(ctx, Spaces_UpdateConfig_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/content.spaces.Spaces/UpdateConfig", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -95,7 +99,43 @@ func (c *spacesClient) UpdateConfig(ctx context.Context, in *UpdateConfigRequest
 
 func (c *spacesClient) Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
 	out := new(emptypb.Empty)
-	err := c.cc.Invoke(ctx, Spaces_Delete_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/content.spaces.Spaces/Delete", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *spacesClient) Transfer(ctx context.Context, in *TransferRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+	out := new(emptypb.Empty)
+	err := c.cc.Invoke(ctx, "/content.spaces.Spaces/Transfer", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *spacesClient) AbortTransfer(ctx context.Context, in *AbortTransferRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+	out := new(emptypb.Empty)
+	err := c.cc.Invoke(ctx, "/content.spaces.Spaces/AbortTransfer", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *spacesClient) ListTransfers(ctx context.Context, in *ListTransfersRequest, opts ...grpc.CallOption) (*ListTransfersResponse, error) {
+	out := new(ListTransfersResponse)
+	err := c.cc.Invoke(ctx, "/content.spaces.Spaces/ListTransfers", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *spacesClient) AcceptTransfer(ctx context.Context, in *AcceptTransferRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+	out := new(emptypb.Empty)
+	err := c.cc.Invoke(ctx, "/content.spaces.Spaces/AcceptTransfer", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -112,6 +152,19 @@ type SpacesServer interface {
 	Update(context.Context, *UpdateRequest) (*emptypb.Empty, error)
 	UpdateConfig(context.Context, *UpdateConfigRequest) (*emptypb.Empty, error)
 	Delete(context.Context, *DeleteRequest) (*emptypb.Empty, error)
+	// Transfer устанавливает для пространства значение поля RequestedMoveTo. После этого пространство
+	// будет отображаться в списке входящих запросов на перемещение в организации `orgID` (запрос ListIncoming)
+	// С пространством можно продолжать работу в текущей организации, пока запрос на перемещение не будет
+	// принят в целевой организации
+	Transfer(context.Context, *TransferRequest) (*emptypb.Empty, error)
+	// AbortTransfer - отменить перемещение пространства в другую организацию
+	AbortTransfer(context.Context, *AbortTransferRequest) (*emptypb.Empty, error)
+	// ListTransfers возвращает список пространств, перемещение которых было запрошено в текущую организацию
+	ListTransfers(context.Context, *ListTransfersRequest) (*ListTransfersResponse, error)
+	// AcceptTransfer - принять запрос на перемещение пространства. Оно будет перемещено в текущую организацию со
+	// всеми входящими в него данными: ролями, участниками, контентом, пр. и более не будет доступно в
+	// старой организации
+	AcceptTransfer(context.Context, *AcceptTransferRequest) (*emptypb.Empty, error)
 	mustEmbedUnimplementedSpacesServer()
 }
 
@@ -137,6 +190,18 @@ func (UnimplementedSpacesServer) UpdateConfig(context.Context, *UpdateConfigRequ
 func (UnimplementedSpacesServer) Delete(context.Context, *DeleteRequest) (*emptypb.Empty, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented")
 }
+func (UnimplementedSpacesServer) Transfer(context.Context, *TransferRequest) (*emptypb.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method Transfer not implemented")
+}
+func (UnimplementedSpacesServer) AbortTransfer(context.Context, *AbortTransferRequest) (*emptypb.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method AbortTransfer not implemented")
+}
+func (UnimplementedSpacesServer) ListTransfers(context.Context, *ListTransfersRequest) (*ListTransfersResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ListTransfers not implemented")
+}
+func (UnimplementedSpacesServer) AcceptTransfer(context.Context, *AcceptTransferRequest) (*emptypb.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method AcceptTransfer not implemented")
+}
 func (UnimplementedSpacesServer) mustEmbedUnimplementedSpacesServer() {}
 
 // UnsafeSpacesServer may be embedded to opt out of forward compatibility for this service.
@@ -160,7 +225,7 @@ func _Spaces_Create_Handler(srv interface{}, ctx context.Context, dec func(inter
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: Spaces_Create_FullMethodName,
+		FullMethod: "/content.spaces.Spaces/Create",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(SpacesServer).Create(ctx, req.(*CreateRequest))
@@ -178,7 +243,7 @@ func _Spaces_Get_Handler(srv interface{}, ctx context.Context, dec func(interfac
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: Spaces_Get_FullMethodName,
+		FullMethod: "/content.spaces.Spaces/Get",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(SpacesServer).Get(ctx, req.(*GetRequest))
@@ -196,7 +261,7 @@ func _Spaces_List_Handler(srv interface{}, ctx context.Context, dec func(interfa
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: Spaces_List_FullMethodName,
+		FullMethod: "/content.spaces.Spaces/List",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(SpacesServer).List(ctx, req.(*ListRequest))
@@ -214,7 +279,7 @@ func _Spaces_Update_Handler(srv interface{}, ctx context.Context, dec func(inter
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: Spaces_Update_FullMethodName,
+		FullMethod: "/content.spaces.Spaces/Update",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(SpacesServer).Update(ctx, req.(*UpdateRequest))
@@ -232,7 +297,7 @@ func _Spaces_UpdateConfig_Handler(srv interface{}, ctx context.Context, dec func
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: Spaces_UpdateConfig_FullMethodName,
+		FullMethod: "/content.spaces.Spaces/UpdateConfig",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(SpacesServer).UpdateConfig(ctx, req.(*UpdateConfigRequest))
@@ -250,7 +315,7 @@ func _Spaces_Delete_Handler(srv interface{}, ctx context.Context, dec func(inter
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: Spaces_Delete_FullMethodName,
+		FullMethod: "/content.spaces.Spaces/Delete",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(SpacesServer).Delete(ctx, req.(*DeleteRequest))
@@ -258,6 +323,78 @@ func _Spaces_Delete_Handler(srv interface{}, ctx context.Context, dec func(inter
 	return interceptor(ctx, in, info, handler)
 }
 
+func _Spaces_Transfer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(TransferRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(SpacesServer).Transfer(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/content.spaces.Spaces/Transfer",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(SpacesServer).Transfer(ctx, req.(*TransferRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Spaces_AbortTransfer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(AbortTransferRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(SpacesServer).AbortTransfer(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/content.spaces.Spaces/AbortTransfer",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(SpacesServer).AbortTransfer(ctx, req.(*AbortTransferRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Spaces_ListTransfers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ListTransfersRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(SpacesServer).ListTransfers(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/content.spaces.Spaces/ListTransfers",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(SpacesServer).ListTransfers(ctx, req.(*ListTransfersRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Spaces_AcceptTransfer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(AcceptTransferRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(SpacesServer).AcceptTransfer(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/content.spaces.Spaces/AcceptTransfer",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(SpacesServer).AcceptTransfer(ctx, req.(*AcceptTransferRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
 // Spaces_ServiceDesc is the grpc.ServiceDesc for Spaces service.
 // It's only intended for direct use with grpc.RegisterService,
 // and not to be introspected or modified (even as a copy)
@@ -289,6 +426,22 @@ var Spaces_ServiceDesc = grpc.ServiceDesc{
 			MethodName: "Delete",
 			Handler:    _Spaces_Delete_Handler,
 		},
+		{
+			MethodName: "Transfer",
+			Handler:    _Spaces_Transfer_Handler,
+		},
+		{
+			MethodName: "AbortTransfer",
+			Handler:    _Spaces_AbortTransfer_Handler,
+		},
+		{
+			MethodName: "ListTransfers",
+			Handler:    _Spaces_ListTransfers_Handler,
+		},
+		{
+			MethodName: "AcceptTransfer",
+			Handler:    _Spaces_AcceptTransfer_Handler,
+		},
 	},
 	Streams:  []grpc.StreamDesc{},
 	Metadata: "spaces/spaces.proto",
-- 
GitLab