-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* GO-3194 WiP * GO-3194 Add MembershipGetVerificationEmailStatus * GO-3194 Updated .proto file * GO-3194 More comments * GO-3194 Added NS name type * GO-3194 Refactor nameservice, implement proto changes * GO-3194 Linter
- Loading branch information
1 parent
3a78649
commit f573352
Showing
15 changed files
with
4,360 additions
and
2,835 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
package nameservice | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/anyproto/any-sync/app" | ||
"github.com/anyproto/any-sync/nameservice/nameserviceclient" | ||
|
||
"github.com/anyproto/anytype-heart/core/wallet" | ||
"github.com/anyproto/anytype-heart/pb" | ||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model" | ||
|
||
proto "github.com/anyproto/any-sync/nameservice/nameserviceproto" | ||
) | ||
|
||
const CName = "nameservice" | ||
|
||
func NsNameToFullName(nsName string, nsNameType model.NameserviceNameType) string { | ||
if nsNameType == model.NameserviceNameType_AnyName { | ||
return nsName + ".any" | ||
} | ||
|
||
// by default return it | ||
return nsName | ||
} | ||
|
||
type Service interface { | ||
NameServiceResolveName(ctx context.Context, req *pb.RpcNameServiceResolveNameRequest) *pb.RpcNameServiceResolveNameResponse | ||
NameServiceResolveAnyId(ctx context.Context, req *pb.RpcNameServiceResolveAnyIdRequest) *pb.RpcNameServiceResolveAnyIdResponse | ||
NameServiceUserAccountGet(ctx context.Context, req *pb.RpcNameServiceUserAccountGetRequest) *pb.RpcNameServiceUserAccountGetResponse | ||
|
||
app.Component | ||
} | ||
|
||
func New() Service { | ||
return &service{} | ||
} | ||
|
||
type service struct { | ||
nsclient nameserviceclient.AnyNsClientService | ||
wallet wallet.Wallet | ||
} | ||
|
||
func (s *service) Name() (name string) { | ||
return CName | ||
} | ||
|
||
func (s *service) Init(a *app.App) (err error) { | ||
// Get name service object that connects to the remote "namingNode" | ||
// in order for that to work, we need to have a "namingNode" node in the nodes section of the config | ||
s.nsclient = app.MustComponent[nameserviceclient.AnyNsClientService](a) | ||
s.wallet = app.MustComponent[wallet.Wallet](a) | ||
return nil | ||
} | ||
|
||
func (s *service) NameServiceResolveName(ctx context.Context, req *pb.RpcNameServiceResolveNameRequest) *pb.RpcNameServiceResolveNameResponse { | ||
var in proto.NameAvailableRequest | ||
in.FullName = NsNameToFullName(req.NsName, req.NsNameType) | ||
|
||
nar, err := s.nsclient.IsNameAvailable(ctx, &in) | ||
if err != nil { | ||
return &pb.RpcNameServiceResolveNameResponse{ | ||
Error: &pb.RpcNameServiceResolveNameResponseError{ | ||
// we don't map error codes here | ||
Code: pb.RpcNameServiceResolveNameResponseError_UNKNOWN_ERROR, | ||
Description: err.Error(), | ||
}, | ||
} | ||
} | ||
|
||
// Return the response | ||
var out pb.RpcNameServiceResolveNameResponse | ||
out.Available = nar.Available | ||
out.OwnerAnyAddress = nar.OwnerAnyAddress | ||
// EOA is onwer of -> SCW is owner of -> name | ||
out.OwnerEthAddress = nar.OwnerEthAddress | ||
out.OwnerScwEthAddress = nar.OwnerScwEthAddress | ||
out.SpaceId = nar.SpaceId | ||
out.NameExpires = nar.NameExpires | ||
|
||
return &out | ||
} | ||
|
||
func (s *service) NameServiceResolveAnyId(ctx context.Context, req *pb.RpcNameServiceResolveAnyIdRequest) *pb.RpcNameServiceResolveAnyIdResponse { | ||
var in proto.NameByAnyIdRequest | ||
in.AnyAddress = req.AnyId | ||
|
||
nar, err := s.nsclient.GetNameByAnyId(ctx, &in) | ||
if err != nil { | ||
return &pb.RpcNameServiceResolveAnyIdResponse{ | ||
Error: &pb.RpcNameServiceResolveAnyIdResponseError{ | ||
// we don't map error codes here | ||
Code: pb.RpcNameServiceResolveAnyIdResponseError_UNKNOWN_ERROR, | ||
Description: err.Error(), | ||
}, | ||
} | ||
} | ||
|
||
// Return the response | ||
var out pb.RpcNameServiceResolveAnyIdResponse | ||
out.Found = nar.Found | ||
out.FullName = nar.Name | ||
|
||
return &out | ||
} | ||
|
||
func (s *service) NameServiceUserAccountGet(ctx context.Context, req *pb.RpcNameServiceUserAccountGetRequest) *pb.RpcNameServiceUserAccountGetResponse { | ||
// when AccountAbstraction is used to deploy a smart contract wallet | ||
// then name is really owned by this SCW, but owner of this SCW is | ||
// EOA that was used to sign transaction | ||
// | ||
// EOA (w.GetAccountEthAddress()) -> SCW (ua.OwnerSmartContracWalletAddress) -> name | ||
var guar proto.GetUserAccountRequest | ||
guar.OwnerEthAddress = s.wallet.GetAccountEthAddress().Hex() | ||
|
||
ua, err := s.nsclient.GetUserAccount(ctx, &guar) | ||
if err != nil { | ||
return &pb.RpcNameServiceUserAccountGetResponse{ | ||
Error: &pb.RpcNameServiceUserAccountGetResponseError{ | ||
Code: pb.RpcNameServiceUserAccountGetResponseError_UNKNOWN_ERROR, | ||
Description: err.Error(), | ||
}, | ||
} | ||
} | ||
|
||
// 4 - check if any name is attached to the account (reverse resolve the name) | ||
var in proto.NameByAddressRequest | ||
|
||
// NOTE: we are passing here SCW address, not initial ETH address! | ||
// read comment about SCW above please | ||
in.OwnerScwEthAddress = ua.OwnerSmartContracWalletAddress | ||
|
||
nar, err := s.nsclient.GetNameByAddress(ctx, &in) | ||
if err != nil { | ||
return &pb.RpcNameServiceUserAccountGetResponse{ | ||
Error: &pb.RpcNameServiceUserAccountGetResponseError{ | ||
// we don't map error codes here | ||
Code: pb.RpcNameServiceUserAccountGetResponseError_BAD_NAME_RESOLVE, | ||
Description: err.Error(), | ||
}, | ||
} | ||
} | ||
|
||
// Return the response | ||
var out pb.RpcNameServiceUserAccountGetResponse | ||
out.NamesCountLeft = ua.NamesCountLeft | ||
out.OperationsCountLeft = ua.OperationsCountLeft | ||
// not checking nar.Found here, no need | ||
out.AnyNameAttached = nar.Name | ||
|
||
return &out | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package nameservice | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestNsNameToFullName(t *testing.T) { | ||
t.Run("should succeed", func(t *testing.T) { | ||
out := NsNameToFullName("somename", model.NameserviceNameType_AnyName) | ||
require.Equal(t, "somename.any", out) | ||
|
||
// by default return no suffix without error | ||
// in this case other NS methods should check the validity and return an error | ||
out = NsNameToFullName("tony", 1) | ||
require.Equal(t, "tony", out) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.