All files / src/components/views/Credentials/CredentialShare ShareViaDidComm.tsx

0% Statements 0/38
0% Branches 0/22
0% Functions 0/5
0% Lines 0/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107                                                                                                                                                                                                                     
import { useContext, useState, useEffect } from "react";
import { Box, Button, Flex, Form, Flash, Loader } from "rimble-ui";
import { Send } from "@rimble/icons";
import { VC } from "vc-schema-tools";
import { DidSearchWithMessagingInfo } from "../../../elements/DidSearchWithMessagingInfo";
import { SertoUiContext, SertoUiContextInterface } from "../../../../context/SertoUiContext";
 
export interface ShareViaDidCommProps {
  vc: VC;
}
 
export const ShareViaDidComm: React.FunctionComponent<ShareViaDidCommProps> = (props) => {
  const { vc } = props;
  const context = useContext<SertoUiContextInterface>(SertoUiContext);
  const [loading, setLoading] = useState(false);
  const [success, setSuccess] = useState(false);
  const [error, setError] = useState("");
  const [recipientDid, setRecipientDid] = useState("");
  const [recipientSupportsMessaging, setRecipientSupportsMessaging] = useState(false);
 
  useEffect(() => {
    setError("");
  }, [recipientDid, recipientSupportsMessaging]);
 
  async function sendVc(e: Event) {
    e.preventDefault();
    if (!recipientDid || !recipientSupportsMessaging) {
      return;
    }
    if (!context.sendVc) {
      console.error("serto-ui context missing sendVc", context);
      setError("This Serto instance is missing the ability to send VCs via DIDComm.");
      return;
    }
 
    setError("");
    setLoading(true);
    setSuccess(false);
 
    try {
      let senderDid = typeof vc.issuer === "string" ? vc.issuer : vc.issuer.id;
      const senderDidBelongsToUser = context.userDids?.some((did) => did.did === senderDid);
      if (!senderDidBelongsToUser) {
        if (!context.userDids?.[0]) {
          throw Error(
            `VC issuer DID ${senderDid} does not belong to user, and could not get any user DIDs to use as DIDComm sender`,
          );
        }
 
        // @TODO/tobek Is this the right behavior in this case?
        console.warn(
          `VC issuer ${senderDid} does not belong to user, sending VC from user's first DID instead`,
          context.userDids[0],
        );
        senderDid = context.userDids[0].did;
      }
 
      await context.sendVc(senderDid, recipientDid, vc);
    } catch (err) {
      console.error("failed to send VC:", err);
      setError("Failed to send credential to subject: " + err.message);
      setLoading(false);
      return;
    }
 
    setLoading(false);
    setSuccess(true);
  }
 
  return (
    <Form onSubmit={sendVc}>
      <Flex>
        <Box width="100%">
          <DidSearchWithMessagingInfo
            required
            onChange={(val) => setRecipientDid(val.did)}
            supportsMessaging={recipientSupportsMessaging}
            setSupportsMessaging={setRecipientSupportsMessaging}
            messagingUnsupportedText="This DID does not support receiving credentials via DIDComm."
          />
        </Box>
        <Button type="submit" disabled={!recipientDid || !recipientSupportsMessaging} ml={2}>
          <Flex alignItems="center">
            {loading ? (
              <Loader color="white" />
            ) : (
              <>
                <Send size="24px" mr={2} /> Send
              </>
            )}
          </Flex>
        </Button>
      </Flex>
      {recipientDid && error && (
        <Flash mt={3} variant="danger">
          {error}
        </Flash>
      )}
      {recipientDid && success && (
        <Flash mt={3} variant="success">
          Credential sent successfully.
        </Flash>
      )}
    </Form>
  );
};