Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 23 Next »

This ruleset has been designed to facilitate the implementation of the DIDExchange protocol. It serves as a comprehensive illustration of the dido.ts library and can be immensely beneficial for integrating additional protocols. The following is an explanation of the different rules and methods in the dido ruleset, did-o.krl, to aid with further comprehension.

How To Use

A developer might follow these instructions to use the did-o.krl ruleset.

  1. Install the did-o ruleset in the pico engine by running the command pico-engine import <path/to/did-o/ruleset-directory>.

  2. Create a channel for the pico by calling the wrangler:channels(tag) function and passing a tag. This function will return an event channel ID (ECI) that the pico can use to communicate with other picos.

  3. Call the create_DID(type, endpoint) function to generate a DID for the pico. The type argument should be set to the DID method being used, and the endpoint argument should be set to the URL of the pico's event endpoint.

  4. Call the get_explicit_invite() function to retrieve the explicit invitation message for the pico.

  5. Send the explicit invitation message to another pico via a secure channel.

  6. Once the other pico receives the explicit invitation message, it can generate a response message by calling the generate_response_message(my_did_doc, invite_id, their_did) function. The my_did_doc argument should be set to the DID document of the responding pico, the invite_id argument should be set to the ID of the explicit invitation message, and the their_did argument should be set to the DID of the initiating pico.

  7. The responding pico can then send the response message to the initiating pico via a secure channel.

  8. Once the initiating pico receives the response message, it can generate a complete message by calling the generate_complete_message(thid, pthid) function. The thid argument should be set to the thread ID of the exchange, and the pthid argument should be set to the parent thread ID of the exchange.

  9. The initiating pico can then send the complete message to the responding pico via a secure channel.

  10. At this point, the DID exchange is complete, and the picos can use DIDComm to communicate securely. To send a message via DIDComm, call the send(did, message) function, where did is the DID of the intended recipient and message is the message to be sent. The recipient pico can then receive the message via its event endpoint and process it accordingly.

Functions

addRoute(type, _domain, name)

Add a route to the routes stored in the dido.ts library.

// This ruleset was imported in the TicTacToe example as didx // You cannot use the connections established in this rule in other rules unless it's through this rule.
route0 = didx:addRoute("did:sov:SLfEi9esrjzybysFxQZbfq;spec/tictactoe/1.0/move", "tictactoe", "receive_move") // Example from TicTacToe library

Routes are used to guide didcomm_v2 messages to their proper rules in a ruleset.

send(did, message)

Send a message to the specified did.

// This ruleset was imported in the TicTacToe example as didx
didx:send(game{"did"}, message) // Example from TicTacToe library

create_DID(type, endpoint)

Generate a new DID and DID document that includes the generated public key, authentication key, and service endpoint information. The DID document is stored in the didDocs resource and the private keys are stored in the didSecrets resource.

// whole_DID contians DID and DIDDoc
whole_DID = dido:send("peer", endpoint)

getECI(tag)

Retrieve the most recently created channel ID that matches a given tag.

eci = dido:getECI("did_o_invite")

getHost()

Return the value of host entity in the current context.

// gets hostname or IP address of the machine
IP_address = dido:getHost()

getRoutes()

Return the routes attributes of the current entity which is a list of routes.

routes = dido:getRoutes()

getDidMap()

Return the map of DIDs stored in the entity.

// returns all DID and DIDDocs used in the did exchange
dido:getDidMap()

clearDidMap()

Clear the map of DIDs entity.

// clears the didMap entity in the resource state
dido:clearDidMap()

create_end_point(eci)

Create an endpoint for sending DIDComm v2 messages to a specific ECI the map of DIDs in the entity.

// endpoint to send DIDComm messages
endpoint = dido:create_end_point(clg2gvggh001rohmnfcnz0oxo)

clearDidDocs()

Clear the didDocs entity.

// the map of DIDDocs is empty after the call to the function
dido:createDidDocs()

get_PendingRequests()

Return all the requests received to determine which one will be accepted.

// the entity map of requests will be returned
pending_requests = dido:get_PendingRequests() // request_id to request_message map

get_explicit_invite()

Return all the requests received to determine which one will be accepted.

// the entity map of requests will be returned
pending_requests = dido:get_PendingRequests() // request_id to request_message map

get_invitation_did_doc()

Return the DID used for the latest created explicit invitation.

invitation_did = get_invitation_did_doc() // returns DID only

create_explicit_invitation(new_id)

Create an explicit invitation object that includes a type, ID, sender, and body. The type specifies the type of invitation being created, and the ID is the unique identifier for the invitation. The sender is set to the same ID as the invitation, and the body includes additional information about the invitation, such as the goal of the exchange, a label for the invitation, and the communication protocol to be used.

// new_id is a DID
explicit_incitation = create_explicit_invitation(did:peer:0z6MkfBQPaMURL5j6Xyvrqh4S5TH91jjVNMZdHbEFFBgDDNaq)

generate_response_message(my_did_doc, invite_id, their_did)

Create a response message for a DID exchange. The message object includes an ID, type, transaction ID (thid), parent transaction ID (pthid), and a body. The function is takes three parameters: my_did_doc, invite_id, and their_did. my_did_doc is used to provide the DID of the newly generated DID and DIDDoc for the response message, invite_id is the ID of the invitation, and their_did is the DID of the recipient.

// response message for DID exchange
response_message = create_response_message(my_did_doc, did:peer:0z6MkfBQPaMURL5j6Xyvrqh4S5TH91jjVNMZdHbEFFBgDDNaq, did:peer:0z6MkfBQPaMURL5j6Xyvrqh4S5TH91jjVNMZdHbEFFBgDDNaq)

generate_request_message(invite_id, my_did_doc, label)

Create a request message for a DID exchange. The function creates a request message object that includes an ID, a type, a transaction ID (thid), a parent transaction ID (pthid), and a body. The ID is set to the sender's DID, the type specifies the type of message being sent, and the thid and pthid fields are used to track the exchange transaction. The body field includes information about the sender's DID, a label for the request, and a goal for the exchange. The second parameter, my_did_doc, is used to retrieve the DID from the DIDDoc created for this request message.

// label example: 
// label = invite{"body"}{"label"}
request_message = generate_request_message(did:peer:0z6MkfBQPaMURL5j6Xyvrqh4S5TH91jjVNMZdHbEFFBgDDNaq, did:peer:0z6MkfBQPaMURL5j6Xyvrqh4S5TH91jjVNMZdHbEFFBgDDNaq, label)

generate_complete_message(thid, pthid)

Create a message indicating that the exchange of DIDs between two parties has been completed. for a DID exchange. The function creates a message object that includes a type, an ID, a transaction ID (thid), a parent transaction ID (pthid), and an empty body. The type specifies that this message is a "complete" message indicating that the exchange is complete.

complete_message = generate_complete_message(did:peer:0z6MkfBQPaMURL5j6Xyvrqh4S5TH91jjVNMZdHbEFFBgDDNaq, did:peer:0z6MkfBQPaMURL5j6Xyvr1128yadj1jjVNMZdHbEFFBgDDNaq)

Defactions

create_new_endpoint(label)

The custom action creates a new channel using the provided label and return the endpoint ID.

//label = "PicoInvite"
endpoint_ID = create_new_endpoint(lebel)

Rules

intialize

The initialize rule is used to initialize the pendingRequests, routes and host variable.

set_host

This rule is used to set a new host variable. You need to change this when you host a instance of the pico engine.

route_message

The route_message rule is called whenever you receive a didcommv2_message. It calls the dido library and looks for the proper route based on the message type. It then raises the appropriate rule and passes along the message.

receive_invite

The receive_invite rule takes an invite url (example.com_oob=abc…123). The invite url is a base 64 encoded invite. The rule then creates an endpoint. After the new endpoint is created it raises the send_request rule.

send_request

The send_request rule creates a request message using generate_request_message and packs that message using dido:pack. Using http:post the message is sent to the service endpoint from the invite.

receive_response

The rule handles incoming responses from other agents and to store their DID documents in the agent’s local storage. The rule also maps the sender’s DID to the current pico’s DID and adds labels to the agent’s channel for the sender’s DID. Finally, the rule raises a send_complete event iwth the necessary attributes if the rule’s actions are successfully completed, or send_error and abandon events if the actions fail.

send_complete

The rule handles the successful completion of sending a message to another agent. The rule packs the complete message using the sender’s DID, the recipient’s DID, and the complete message itself. The packet message is then sent to the recipient agent’s endpoint using an HTTP POST request. Finally, the rule raises a complete event if the actions are successfully completed, or an abandon event if they fail.

complete

The rule should be raised when the complete state has been reached

abandon

This rule is raised if there was an error with the did exchange protocol or an agent decided to stop the connection.

create_explicit_invite

The create_explicit_invite rule is responsible for creating a channel with access control policies, generating a new DID document, creating an explicit invitation, and raising the send_invite rule.

The create_explicit_invite rule is triggered when a dido create_explicit_invitation event is received by the Pico engine. The rule begins by setting the tag variable to ["did_o_invite"]. This tag variable is used to identify the channel that the rule will create using wrangler:createChannel. The eventPolicy and queryPolicy variables define the access control policies for the channel. The eventPolicy allows any domain with the name "*" to access the channel, while the queryPolicy only allows the current rule's meta:rid to access the channel.

The wrangler:createChannel method creates a channel with the specified tag and access control policies. The fired block is executed when the rule is triggered and the channel is created. Inside the fired block, the create_end_point method is used to create an endpoint based on the tag specified earlier. This endpoint is then used to create a DID document using the create_DID method, which returns a new DID that can be used for the invitation.

The new_id variable holds the newly created DID, which is also set as the public key. The create_explicit_invitation method is then used to create the actual invitation, which includes the DID, public key, and endpoint. The ent:invitation_DID and ent:explicit_invite variables are set to the DID and explicit invitation, respectively.

Finally, the dido event "send_invite" rule is raised to send the invitation to the intended recipient. The attributes parameter is used to specify the invitation and endpoint attributes, which are sent as part of the send_invite event.

send_invite

The rule is responsible for encoding and decoding the explicit invitation and sending it to the intended recipient.

The send_invite rule is triggered when a dido send_invite event is received by the Pico engine. In the pre block, the invitation variable is set to the invitation attribute of the event. This attribute was added in the create_explicit_invite rule and contains the details of the explicit invitation that was created.

The base64 variable is set to the base64-encoded string of the invitation. This is achieved by calling the math:base64encode method on the UTF-8 encoded bytes of the invitation string. The resulting encoded string is then logged for debugging purposes.

The decoded variable is set to the decoded invitation. This is done by calling the math:base64decode method on the base64 string and then decoding the resulting byte array back into a string. The decoded invitation is also logged for debugging purposes.

The if statement checks if the invitation variable is not null. If it is not null, the send_directive method is called with the "say" directive and an object containing the "Invite: " and base64 values as key-value pairs.

failed_invite

The rule is responsible to handle errors that occur when creating invitations in the DID agent and to log error message for debugging purposes.

receive_request

The purpose of this rule is to handle incoming requests messages from other agents and store them in a pendingRequests object on the current agent for later processing.

accept_request

The rule listens for the accept _request event. When a new request is accepted, the rule generates a new endpoint ID and raises a new event with the endpoint ID and request message, which can be used to send a response to the original requester. If the rule fails to execute the else block is executed, which raises a new dido abandon event.

decline_request

The rule listens for the decline_request event. When a request is declined, the rule removes the declined request from the pendindRequests entity, which stores pending requests. This ensures that the declined request is not processed further and can be sagely deleted.

send_response

This rule is triggered when send_response event is raised. The purpose of this rule is to generate a response message to a previous request message and send it to the requester. The rule creates a response_message using the DID_doc, thread{"pthid"}, and their_did. It then packs the response_message using the dido:pack() function with the requester's did as the recipient. Finally, it sends the packed message using an HTTP POST request to the requester's end_point using the http:post() function.

receive_complete

This rule is triggered when receive_complete event is raised. This event indicated the communication process has been completed successfully.

exchange_post_response

This KRL rule is triggered when an exchange_post_response event is raised. This rule is intended to handle the case where the HTTP POST request to exchange messages between DIDs fails, and it ensures that the conversation is abandoned if the request was not successful.

received_error

The rule listens for the received_error event. The rule sets the value of variable error_message to the error message contained in the event attributes which indicated where the error is coming from for a better debugging process.

send_trust_ping

The rule sends the trust ping message to the specified DID using the dido:send() function.

receive_trust_ping

The rule unpacks the metadata and message from the event, generates a trust ping response message using the "generate_trust_ping_response()" function, passing in the "id" attribute of the original trust ping message as a parameter, and sends it back to the sender.

Example Using The Testing Tab For DID Exchange

To start a DID Exchange you first need to create an Invite. You can do this in the testing tab by clicking dido:create_explicit_invitation.

The results will contain your invite code.

"Invite: ": "eyJAdHlwZSI6ImRpZDpzb3Y...FuZ2UvMS4wIl19"

The invite code can be passed on and they will begin by making a request using your invite code. In the testing tab, there is a dido:receive_invite where you can begin an exchange using someone’s invite code.

In this implementation when a request is sent for your invite it goes into a list and you have to choose to accept that invite which will store their peer did and share a peer did with the requester. To get a list of those Requests you can use get_PendingRequests

Using the id of the request you can use the dido:accept_request() to finish the DID Exchange Protocol. You can also choose to dido:decline_request() using the request's id.

Example id: did:peer:0z6Mkf9hx1RBR9FM9eZ9PMH5BwhqNgbRNtArFzVrTZGMKw1oC

DID it work?

If the Exchange is completed properly you should be able to look in your logs and there should be no errors. You also should not have gone to an abandoned state.

Then check your DIDs and the DIDMap

You should find your DID and the requester's DID

Try a trust ping with dido:sent_trust_ping using the requester’s DID

If you receive pong back you’ve got a connection and it’s working!

Adding protocols

Check out the tic tac toe ruleset for an example of adding protocols.

  • No labels