Skip to content

Commit

Permalink
Merge pull request #87 from jefft0/feat/API-add-ShareContact-DecodeCo…
Browse files Browse the repository at this point in the history
…ntact

feat: Add API functions ShareContact and DecodeContact
  • Loading branch information
jefft0 committed Jun 27, 2023
2 parents 9100f02 + 482c584 commit 289dbdc
Show file tree
Hide file tree
Showing 8 changed files with 2,079 additions and 671 deletions.
27 changes: 27 additions & 0 deletions api/protocol/protocoltypes.proto
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ service ProtocolService {
// ContactRequestDiscard ignores a contact request, without informing the other user
rpc ContactRequestDiscard (ContactRequestDiscard.Request) returns (ContactRequestDiscard.Reply);

// ShareContact uses ContactRequestReference to get the contact information for the current account and
// returns the Protobuf encoding of a shareable contact which you can further encode and share. If needed, this
// will reset the contact request reference and enable contact requests. To decode the result, see DecodeContact.
rpc ShareContact (ShareContact.Request) returns (ShareContact.Reply);

// DecodeContact decodes the Protobuf encoding of a shareable contact which was returned by ShareContact.
rpc DecodeContact (DecodeContact.Request) returns (DecodeContact.Reply);

// ContactBlock blocks a contact from sending requests
rpc ContactBlock (ContactBlock.Request) returns (ContactBlock.Reply);

Expand Down Expand Up @@ -749,6 +757,25 @@ message ContactRequestDiscard {
message Reply {}
}

message ShareContact {
message Request {}
message Reply {
// encoded_contact is the Protobuf encoding of the ShareableContact. You can further encode the bytes for sharing, such as base58 or QR code.
bytes encoded_contact = 1;
}
}

message DecodeContact {
message Request {
// encoded_contact is the Protobuf encoding of the shareable contact (as returned by ShareContact).
bytes encoded_contact = 1;
}
message Reply {
// shareable_contact is the decoded shareable contact.
ShareableContact contact = 1;
}
}

message ContactBlock {
message Request {
// contact_pk is the identifier of the contact to block
Expand Down
52 changes: 52 additions & 0 deletions api_contact_request_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package weshnet

import (
"context"
"testing"
"time"

libp2p_mocknet "github.com/berty/go-libp2p-mock"
"github.com/stretchr/testify/require"

"berty.tech/weshnet/pkg/protocoltypes"
"berty.tech/weshnet/pkg/testutil"
)

func TestShareContact(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
logger, cleanup := testutil.Logger(t)
defer cleanup()

opts := TestingOpts{
Mocknet: libp2p_mocknet.New(),
Logger: logger,
}

pts, cleanup := NewTestingProtocolWithMockedPeers(ctx, t, &opts, nil, 2)
defer cleanup()

binaryContact, err := pts[0].Client.ShareContact(ctx, &protocoltypes.ShareContact_Request{})
require.NoError(t, err)

// Check that ShareContact reset the contact request reference and enabled contact requests.
contactRequestRef, err := pts[0].Client.ContactRequestReference(ctx,
&protocoltypes.ContactRequestReference_Request{})
require.NoError(t, err)

require.NotEqual(t, 0, len(contactRequestRef.PublicRendezvousSeed))
require.Equal(t, true, contactRequestRef.Enabled)

// Decode.
contact, err := pts[0].Client.DecodeContact(ctx, &protocoltypes.DecodeContact_Request{
EncodedContact: binaryContact.EncodedContact,
})
require.NoError(t, err)

// Check for the expected info.
config, err := pts[0].Client.ServiceGetConfiguration(ctx,
&protocoltypes.ServiceGetConfiguration_Request{})
require.NoError(t, err)
require.Equal(t, contact.Contact.PK, config.AccountPK)
require.Equal(t, contact.Contact.PublicRendezvousSeed, contactRequestRef.PublicRendezvousSeed)
}
67 changes: 67 additions & 0 deletions api_contactrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package weshnet
import (
"context"

"github.com/gogo/protobuf/proto"
"github.com/libp2p/go-libp2p/core/crypto"

"berty.tech/weshnet/pkg/errcode"
Expand Down Expand Up @@ -175,3 +176,69 @@ func (s *service) ContactRequestDiscard(ctx context.Context, req *protocoltypes.

return &protocoltypes.ContactRequestDiscard_Reply{}, nil
}

// ShareContact uses ContactRequestReference to get the contact information for the current account and
// returns the Protobuf encoding which you can further encode and share. If needed, his will reset the
// contact request reference and enable contact requests.
func (s *service) ShareContact(ctx context.Context, req *protocoltypes.ShareContact_Request) (_ *protocoltypes.ShareContact_Reply, err error) {
accountGroup := s.getAccountGroup()
if accountGroup == nil {
return nil, errcode.ErrGroupMissing
}

enabled, shareableContact := accountGroup.MetadataStore().GetIncomingContactRequestsStatus()
rdvSeed := []byte(nil)

if shareableContact != nil {
rdvSeed = shareableContact.PublicRendezvousSeed
}

if !enabled || len(rdvSeed) == 0 {
// We need to enable and reset the contact request reference.
if _, err := accountGroup.MetadataStore().ContactRequestEnable(ctx); err != nil {
return nil, errcode.ErrOrbitDBAppend.Wrap(err)
}

if _, err := accountGroup.MetadataStore().ContactRequestReferenceReset(ctx); err != nil {
return nil, errcode.ErrOrbitDBAppend.Wrap(err)
}

// Refresh the info.
_, shareableContact = accountGroup.MetadataStore().GetIncomingContactRequestsStatus()
rdvSeed = []byte(nil)

if shareableContact != nil {
rdvSeed = shareableContact.PublicRendezvousSeed
}
}

// Get the client's AccountPK.
member, err := accountGroup.MemberPubKey().Raw()
if err != nil {
return nil, errcode.ErrSerialization.Wrap(err)
}

encodedContact, err := proto.Marshal(&protocoltypes.ShareableContact{
PK: member,
PublicRendezvousSeed: rdvSeed,
})
if err != nil {
return nil, err
}

return &protocoltypes.ShareContact_Reply{
EncodedContact: encodedContact,
}, nil
}

// DecodeContact decodes the Protobuf encoding of a shareable contact which was returned by ShareContact.
func (s *service) DecodeContact(ctx context.Context, req *protocoltypes.DecodeContact_Request) (_ *protocoltypes.DecodeContact_Reply, err error) {
contact := &protocoltypes.ShareableContact{}
if err := proto.Unmarshal(req.EncodedContact, contact); err != nil {
panic(err)
}

return &protocoltypes.DecodeContact_Reply{
Contact: contact,
}, nil
}
44 changes: 44 additions & 0 deletions docs/apis/protocoltypes.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions docs/apis/protocoltypes.swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 289dbdc

Please sign in to comment.