github.com/hyperledger/aries-framework-go@v0.3.2/pkg/client/issuecredential/example_test.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package issuecredential
     8  
     9  import (
    10  	"encoding/json"
    11  	"fmt"
    12  	"time"
    13  
    14  	"github.com/golang/mock/gomock"
    15  
    16  	"github.com/hyperledger/aries-framework-go/component/storageutil/mem"
    17  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
    18  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/messenger"
    19  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/issuecredential"
    20  	mocks "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/client/presentproof"
    21  	dispatchermocks "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/didcomm/dispatcher"
    22  	messengermocks "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/didcomm/messenger"
    23  	protocolmocks "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/didcomm/protocol/presentproof"
    24  	"github.com/hyperledger/aries-framework-go/pkg/store/connection"
    25  )
    26  
    27  // payload represents a transport message structure.
    28  type payload struct {
    29  	msg      []byte
    30  	myDID    string
    31  	theirDID string
    32  }
    33  
    34  //nolint:forbidigo
    35  func mockContext(agent string, tr map[string]chan payload) Provider {
    36  	ctrl := gomock.NewController(nil)
    37  
    38  	outbound := dispatchermocks.NewMockOutbound(ctrl)
    39  	outbound.EXPECT().
    40  		SendToDID(gomock.Any(), gomock.Any(), gomock.Any()).
    41  		DoAndReturn(func(msg interface{}, myDID, theirDID string) error {
    42  			src, err := json.Marshal(msg)
    43  			if err != nil {
    44  				fmt.Println(err)
    45  			}
    46  
    47  			tr[theirDID] <- payload{
    48  				msg:      src,
    49  				myDID:    theirDID,
    50  				theirDID: myDID,
    51  			}
    52  
    53  			return nil
    54  		}).AnyTimes()
    55  
    56  	store := mem.NewProvider()
    57  
    58  	mProvider := messengermocks.NewMockProvider(ctrl)
    59  	mProvider.EXPECT().StorageProvider().Return(store)
    60  	mProvider.EXPECT().OutboundDispatcher().Return(outbound)
    61  
    62  	msgSvc, err := messenger.NewMessenger(mProvider)
    63  	if err != nil {
    64  		fmt.Println(err)
    65  	}
    66  
    67  	provider := protocolmocks.NewMockProvider(ctrl)
    68  	provider.EXPECT().StorageProvider().Return(store).MaxTimes(2)
    69  	provider.EXPECT().Messenger().Return(msgSvc)
    70  
    71  	svc, err := issuecredential.New(provider)
    72  	if err != nil {
    73  		fmt.Println(err)
    74  	}
    75  
    76  	go func() {
    77  		for {
    78  			select {
    79  			case msg := <-tr[agent]:
    80  				didMap, err := service.ParseDIDCommMsgMap(msg.msg)
    81  				if err != nil {
    82  					fmt.Println(err)
    83  				}
    84  
    85  				fmt.Println(agent, "received", didMap.Type(), "from", msg.theirDID)
    86  
    87  				if err = msgSvc.HandleInbound(didMap, service.NewDIDCommContext(msg.myDID, msg.theirDID, nil)); err != nil {
    88  					fmt.Println(err)
    89  				}
    90  
    91  				_, err = svc.HandleInbound(didMap, service.NewDIDCommContext(msg.myDID, msg.theirDID, nil))
    92  				if err != nil {
    93  					fmt.Println(err)
    94  				}
    95  			case <-time.After(time.Second):
    96  				return
    97  			}
    98  		}
    99  	}()
   100  
   101  	mockProvider := mocks.NewMockProvider(ctrl)
   102  	mockProvider.EXPECT().Service(gomock.Any()).Return(svc, nil)
   103  
   104  	return mockProvider
   105  }
   106  
   107  func ExampleClient_SendOffer() {
   108  	transport := map[string]chan payload{
   109  		Alice: make(chan payload),
   110  		Bob:   make(chan payload),
   111  	}
   112  
   113  	// Alice creates client
   114  	clientAlice, err := New(mockContext(Alice, transport))
   115  	if err != nil {
   116  		panic(err)
   117  	}
   118  
   119  	// Alice registers channel for actions.
   120  	actionsAlice := make(chan service.DIDCommAction)
   121  
   122  	err = clientAlice.RegisterActionEvent(actionsAlice)
   123  	if err != nil {
   124  		panic(err)
   125  	}
   126  
   127  	// Bob creates client.
   128  	clientBob, err := New(mockContext(Bob, transport))
   129  	if err != nil {
   130  		panic(err)
   131  	}
   132  
   133  	// Bob registers channel for actions.
   134  	actionsBob := make(chan service.DIDCommAction)
   135  
   136  	err = clientBob.RegisterActionEvent(actionsBob)
   137  	if err != nil {
   138  		panic(err)
   139  	}
   140  
   141  	go func() {
   142  		for {
   143  			var acceptErr error
   144  
   145  			select {
   146  			case e := <-actionsAlice:
   147  				acceptErr = clientAlice.AcceptRequest(e.Properties.All()["piid"].(string), &IssueCredential{})
   148  			case e := <-actionsBob:
   149  				acceptErr = clientBob.AcceptOffer(e.Properties.All()["piid"].(string), &RequestCredential{})
   150  			}
   151  
   152  			if acceptErr != nil {
   153  				fmt.Println(acceptErr)
   154  			}
   155  		}
   156  	}()
   157  
   158  	// Alice.
   159  	waitForAlice := waitForFn(clientAlice)
   160  	// Bob.
   161  	waitForBob := waitForFn(clientBob)
   162  
   163  	_, err = clientAlice.SendOffer(&OfferCredential{}, &connection.Record{MyDID: Alice, TheirDID: Bob})
   164  	if err != nil {
   165  		fmt.Println(err)
   166  	}
   167  
   168  	waitForAlice()
   169  	waitForBob()
   170  
   171  	// Output:
   172  	// Bob received https://didcomm.org/issue-credential/2.0/offer-credential from Alice
   173  	// Alice received https://didcomm.org/issue-credential/2.0/request-credential from Bob
   174  	// Bob received https://didcomm.org/issue-credential/2.0/issue-credential from Alice
   175  	// Alice received https://didcomm.org/issue-credential/2.0/ack from Bob
   176  }
   177  
   178  // nolint: gocyclo
   179  func ExampleClient_SendProposal() {
   180  	transport := map[string]chan payload{
   181  		Alice: make(chan payload),
   182  		Bob:   make(chan payload),
   183  	}
   184  
   185  	// Alice creates client.
   186  	clientAlice, err := New(mockContext(Alice, transport))
   187  	if err != nil {
   188  		panic(err)
   189  	}
   190  
   191  	// Alice registers channel for actions.
   192  	actionsAlice := make(chan service.DIDCommAction)
   193  
   194  	err = clientAlice.RegisterActionEvent(actionsAlice)
   195  	if err != nil {
   196  		panic(err)
   197  	}
   198  
   199  	// Bob creates client.
   200  	clientBob, err := New(mockContext(Bob, transport))
   201  	if err != nil {
   202  		panic(err)
   203  	}
   204  
   205  	// Bob registers channel for actions.
   206  	actionsBob := make(chan service.DIDCommAction)
   207  
   208  	err = clientBob.RegisterActionEvent(actionsBob)
   209  	if err != nil {
   210  		panic(err)
   211  	}
   212  
   213  	go func() {
   214  		for {
   215  			var acceptErr error
   216  
   217  			var e service.DIDCommAction
   218  
   219  			select {
   220  			case e = <-actionsAlice:
   221  			case e = <-actionsBob:
   222  			}
   223  
   224  			piid, ok := e.Properties.All()["piid"].(string)
   225  			if !ok {
   226  				fmt.Println("empty piid")
   227  			}
   228  
   229  			if e.Message.Type() == issuecredential.ProposeCredentialMsgTypeV2 {
   230  				acceptErr = clientAlice.AcceptProposal(piid, &OfferCredential{})
   231  			}
   232  
   233  			if e.Message.Type() == issuecredential.RequestCredentialMsgTypeV2 {
   234  				acceptErr = clientAlice.AcceptRequest(piid, &IssueCredential{})
   235  			}
   236  
   237  			if e.Message.Type() == issuecredential.OfferCredentialMsgTypeV2 {
   238  				acceptErr = clientBob.AcceptOffer(piid, &RequestCredential{})
   239  			}
   240  
   241  			if e.Message.Type() == issuecredential.IssueCredentialMsgTypeV2 {
   242  				acceptErr = clientBob.AcceptCredential(piid)
   243  			}
   244  
   245  			if acceptErr != nil {
   246  				fmt.Println(acceptErr)
   247  			}
   248  		}
   249  	}()
   250  
   251  	// Alice.
   252  	waitForAlice := waitForFn(clientAlice)
   253  	// Bob.
   254  	waitForBob := waitForFn(clientBob)
   255  
   256  	_, err = clientBob.SendProposal(&ProposeCredential{}, &connection.Record{MyDID: Bob, TheirDID: Alice})
   257  	if err != nil {
   258  		fmt.Println(err)
   259  	}
   260  
   261  	waitForAlice()
   262  	waitForBob()
   263  
   264  	// Output:
   265  	// Alice received https://didcomm.org/issue-credential/2.0/propose-credential from Bob
   266  	// Bob received https://didcomm.org/issue-credential/2.0/offer-credential from Alice
   267  	// Alice received https://didcomm.org/issue-credential/2.0/request-credential from Bob
   268  	// Bob received https://didcomm.org/issue-credential/2.0/issue-credential from Alice
   269  	// Alice received https://didcomm.org/issue-credential/2.0/ack from Bob
   270  }
   271  
   272  func ExampleClient_SendRequest() {
   273  	transport := map[string]chan payload{
   274  		Alice: make(chan payload),
   275  		Bob:   make(chan payload),
   276  	}
   277  
   278  	// Alice creates client.
   279  	clientAlice, err := New(mockContext(Alice, transport))
   280  	if err != nil {
   281  		panic(err)
   282  	}
   283  
   284  	// Alice registers channel for actions.
   285  	actionsAlice := make(chan service.DIDCommAction)
   286  
   287  	err = clientAlice.RegisterActionEvent(actionsAlice)
   288  	if err != nil {
   289  		panic(err)
   290  	}
   291  
   292  	// Bob creates client.
   293  	clientBob, err := New(mockContext(Bob, transport))
   294  	if err != nil {
   295  		panic(err)
   296  	}
   297  
   298  	// Bob registers channel for actions.
   299  	actionsBob := make(chan service.DIDCommAction)
   300  
   301  	err = clientBob.RegisterActionEvent(actionsBob)
   302  	if err != nil {
   303  		panic(err)
   304  	}
   305  
   306  	go func() {
   307  		for {
   308  			var acceptErr error
   309  
   310  			select {
   311  			case e := <-actionsAlice:
   312  				acceptErr = clientAlice.AcceptRequest(e.Properties.All()["piid"].(string), &IssueCredential{})
   313  			case e := <-actionsBob:
   314  				acceptErr = clientBob.AcceptCredential(e.Properties.All()["piid"].(string))
   315  			}
   316  
   317  			if acceptErr != nil {
   318  				fmt.Println(acceptErr)
   319  			}
   320  		}
   321  	}()
   322  
   323  	// Alice.
   324  	waitForAlice := waitForFn(clientAlice)
   325  	// Bob.
   326  	waitForBob := waitForFn(clientBob)
   327  
   328  	_, err = clientBob.SendRequest(&RequestCredential{}, &connection.Record{MyDID: Bob, TheirDID: Alice})
   329  	if err != nil {
   330  		fmt.Println(err)
   331  	}
   332  
   333  	waitForAlice()
   334  	waitForBob()
   335  
   336  	// Output:
   337  	// Alice received https://didcomm.org/issue-credential/2.0/request-credential from Bob
   338  	// Bob received https://didcomm.org/issue-credential/2.0/issue-credential from Alice
   339  	// Alice received https://didcomm.org/issue-credential/2.0/ack from Bob
   340  }
   341  
   342  func waitForFn(c *Client) func() {
   343  	const stateDone = "done"
   344  
   345  	agent := make(chan service.StateMsg, 10)
   346  
   347  	if err := c.RegisterMsgEvent(agent); err != nil {
   348  		panic(err)
   349  	}
   350  
   351  	done := make(chan struct{})
   352  
   353  	return func() {
   354  		go func() {
   355  			for st := range agent {
   356  				if st.StateID == stateDone && st.Type == service.PostState {
   357  					done <- struct{}{}
   358  				}
   359  			}
   360  		}()
   361  
   362  		select {
   363  		case <-done:
   364  		case <-time.After(time.Second):
   365  			fmt.Println("timeout") //nolint:forbidigo
   366  		}
   367  	}
   368  }