# Mission3 (Player) ```plantuml @startuml header Overall mission flow diagram title Overall Mission Flow (PLAYER) end title autonumber "[0]" actor "Player" as PLAYER order 0 actor "Admin" as ADMIN order 1 participant "Wallet" as WALLET order 2 participant "Browser" as BROWSER order 3 control "NextApi" as NEXTAPI order 4 #Gray control "InfuraApi" as INFURA order 5 #Gray database "Firebase" as FIREBASE order 6 #Gray entity "PompHub\nContract" as POMPCONTRACT order 7 #White entity "ProfileModule\nContract" as PROFILECONTRACT order 8 #White entity "MissionModule\nContract" as MISSIONCONTRACT order 9 #White entity "MissionNFT\nContract" as MISSIONNFT order 10 #White actor "Verifier" as VERIFIER order 11 #Gray == Request Whitelisting == PLAYER->ADMIN: (out-of-band)\nrequest whitelist ADMIN-->PLAYER: (out-of-band)\nconfirmation ADMIN->NEXTAPI: (out-of-band) update whitelisted profiles ADMIN->POMPCONTRACT: (out-of-band) Write contract\nsetMerkelrootForProfiles (rootHash) POMPCONTRACT->PROFILECONTRACT: request PROFILECONTRACT-->POMPCONTRACT: (void) autonumber "[0]" == Create Profile == PLAYER->BROWSER: fetch website activate BROWSER BROWSER->BROWSER: authenticate BROWSER->POMPCONTRACT: Read contract\n1. claimed\n2. profileIdByAddress\n3. canClaim\n4. merkleroot POMPCONTRACT->PROFILECONTRACT: request PROFILECONTRACT-->POMPCONTRACT: response POMPCONTRACT-->BROWSER: (boolean, profileId, boolean, bytes32) BROWSER->NEXTAPI: GET /whitelist/[address] NEXTAPI-->BROWSER: (proof, verified, rootHash) BROWSER->BROWSER: Compare rootHash from\nNextApi & PompContract BROWSER->BROWSER: Input handle BROWSER->POMPCONTRACT: Read contract\nprofileIdByHandle (handle) POMPCONTRACT->PROFILECONTRACT: request PROFILECONTRACT-->POMPCONTRACT: response POMPCONTRACT-->BROWSER: (boolean) BROWSER->BROWSER: isHandleAvailable BROWSER->WALLET: sign transaction deactivate BROWSER activate WALLET WALLET->PLAYER: request signing activate PLAYER PLAYER->WALLET: signature deactivate PLAYER WALLET->BROWSER: signature deactivate WALLET activate BROWSER BROWSER->POMPCONTRACT: createProfile(handle, proof) POMPCONTRACT->PROFILECONTRACT: request PROFILECONTRACT-->POMPCONTRACT: response POMPCONTRACT-->BROWSER: (hash, wait) deactivate BROWSER BROWSER->POMPCONTRACT: Read contract\nprofileById (profileId) activate BROWSER POMPCONTRACT->PROFILECONTRACT: request PROFILECONTRACT-->POMPCONTRACT: response POMPCONTRACT-->BROWSER: (ProfileStruct) deactivate BROWSER loop poll (optional) BROWSER->POMPCONTRACT: wait (1) POMPCONTRACT-->BROWSER: (receipt) BROWSER->BROWSER: parse log end autonumber "[0]" == Start Mission (Escrow) == PLAYER->BROWSER: fetch website BROWSER->BROWSER: Pick mission /m/[objectId] BROWSER->BROWSER: authenticate BROWSER->BROWSER: route to Start component BROWSER->POMPCONTRACT: missionIdBySlug POMPCONTRACT->MISSIONCONTRACT: request MISSIONCONTRACT-->POMPCONTRACT: response POMPCONTRACT-->BROWSER: (missionId) BROWSER->BROWSER: isNameAvailable BROWSER->POMPCONTRACT: getRoleHash (VERIFIER) POMPCONTRACT-->BROWSER: (roleHash) BROWSER->POMPCONTRACT: hasRole (roleHash, wallet) POMPCONTRACT-->BROWSER: (boolean) note over BROWSER : All checks pass group Submit [startWithSig] BROWSER->INFURA: 1.Prepare metadata\n2.Ipfs-upload (metadata) activate BROWSER INFURA-->BROWSER: (ipfsUrl) BROWSER->NEXTAPI: createStartTypedData\n(profileId, slug,\ncontentURI, verifier,\nminutesToExpire) NEXTAPI->POMPCONTRACT: getSigNonce and\nmissionModuleAddress POMPCONTRACT->MISSIONCONTRACT: request MISSIONCONTRACT-->POMPCONTRACT: response POMPCONTRACT-->NEXTAPI: (sigNonce, address) NEXTAPI->NEXTAPI: getDeadline NEXTAPI-->BROWSER: (startWithSigTypedData) BROWSER->WALLET: sign (eip-712) deactivate BROWSER WALLET->PLAYER: request signing PLAYER-->WALLET: (signature) WALLET-->BROWSER: (signature) BROWSER->WALLET: writeAsync\n(startWithSig) deactivate BROWSER WALLET->PLAYER: send transaction PLAYER->WALLET: confirm WALLET->BROWSER: confirm BROWSER->POMPCONTRACT: startWithSig\n(profileId, slug, contentURI, verifier,\nminutesToExpire, signature, msg.sender) activate BROWSER POMPCONTRACT->PROFILECONTRACT: owner (profileId) PROFILECONTRACT-->POMPCONTRACT: (address) note over POMPCONTRACT: TODO: Missing Implementation\nEIP 2981 set royalty & receiver POMPCONTRACT->MISSIONCONTRACT: startWithSig MISSIONCONTRACT->MISSIONCONTRACT: verify signature\n& deadline MISSIONCONTRACT->MISSIONNFT: safeMint MISSIONNFT-->MISSIONCONTRACT: mintTo\nPOMPCONTRACT MISSIONNFT->MISSIONNFT: setTokenRoyalty MISSIONCONTRACT->MISSIONCONTRACT: emit Started MISSIONCONTRACT-->POMPCONTRACT: (void) POMPCONTRACT-->BROWSER: (hash, wait) deactivate BROWSER loop poll BROWSER->POMPCONTRACT: wait (1) POMPCONTRACT-->BROWSER: (receipt) BROWSER->BROWSER: parse log end group Optional [Confirmations] note over FIREBASE: Not implemented yet BROWSER->FIREBASE: trigger confirmations (txHash) FIREBASE-->BROWSER: (void) end end autonumber "[0]" == Abort Mission == PLAYER->BROWSER: fetch website BROWSER->BROWSER: browse mission BROWSER->NEXTAPI: createAbortTypedData\n(profileId, missionId) activate BROWSER NEXTAPI->POMPCONTRACT: getSigNonce and\nmissionModuleAddress POMPCONTRACT->MISSIONCONTRACT: request MISSIONCONTRACT-->POMPCONTRACT: response POMPCONTRACT-->NEXTAPI: (sigNonce, address) NEXTAPI->NEXTAPI: getDeadline NEXTAPI-->BROWSER: (abortWithSigTypedData) BROWSER->WALLET: sign (eip-712) deactivate BROWSER WALLET->PLAYER: request signing PLAYER-->WALLET: (signature) WALLET-->BROWSER: (signature) BROWSER->WALLET: writeAsync\n(abortWithSig) WALLET->PLAYER: send transaction PLAYER->WALLET: confirm WALLET->BROWSER: confirm BROWSER->POMPCONTRACT: abortWithSig\n(profileId, missionId, signature, deadline, msg.sender) activate BROWSER POMPCONTRACT->PROFILECONTRACT: owner (profileId) PROFILECONTRACT-->POMPCONTRACT: (address) POMPCONTRACT->MISSIONCONTRACT: abortWithSig MISSIONCONTRACT->MISSIONCONTRACT: verify signature\n& deadline MISSIONCONTRACT->MISSIONNFT: _burn (tokenId) MISSIONNFT->MISSIONNFT: _resetTokenRoyalty (tokenId) MISSIONNFT-->MISSIONCONTRACT: (void) MISSIONCONTRACT->MISSIONCONTRACT: State.Aborted MISSIONCONTRACT->MISSIONCONTRACT: emit Aborted MISSIONCONTRACT-->POMPCONTRACT: (void) POMPCONTRACT-->BROWSER: (hash, wait) deactivate BROWSER loop poll BROWSER->POMPCONTRACT: wait (1) POMPCONTRACT-->BROWSER: (receipt) BROWSER->BROWSER: parse log end autonumber "[0]" == (Out-of-band) Challenge generation == loop generate VERIFIER->BROWSER: fetch website activate BROWSER BROWSER->NEXTAPI: generateChallenge () NEXTAPI-->BROWSER: (code_verifier, code_challenge) BROWSER->VERIFIER: (code_verifier, code_challenge) deactivate BROWSER VERIFIER->VERIFIER: Save end PLAYER->VERIFIER: (out-of-band)\nObtain challenge (profileId, missionId) activate VERIFIER VERIFIER->VERIFIER: Save\n(profileId,\nmissionId,\ncode_verifier) VERIFIER-->PLAYER: (challenge) deactivate VERIFIER autonumber "[0]" == Complete Mission == PLAYER->BROWSER: fetch website BROWSER->BROWSER: Browse mission BROWSER->BROWSER: Input challenge BROWSER->NEXTAPI: createCompleteTypedData\n(profileId, missionId,\nchallenge) activate BROWSER NEXTAPI->POMPCONTRACT: getSigNonce and\nmissionModuleAddress POMPCONTRACT->MISSIONCONTRACT: request MISSIONCONTRACT-->POMPCONTRACT: response POMPCONTRACT-->NEXTAPI: (sigNonce, address) NEXTAPI->NEXTAPI: getDeadline NEXTAPI-->BROWSER: (completeWithSigTypedData) BROWSER->WALLET: sign (eip-712) deactivate BROWSER WALLET->PLAYER: request signing PLAYER-->WALLET: (signature) WALLET-->BROWSER: (signature) BROWSER->WALLET: writeAsync\n(completeWithSig) WALLET->PLAYER: send transaction PLAYER->WALLET: confirm WALLET->BROWSER: confirm BROWSER->POMPCONTRACT: completeWithSig\n(profileId, missionId, challenge,\nsignature, deadline, msg.sender) activate BROWSER POMPCONTRACT->PROFILECONTRACT: owner (profileId) PROFILECONTRACT-->POMPCONTRACT: (address) POMPCONTRACT->MISSIONCONTRACT: completeWithSig MISSIONCONTRACT->MISSIONCONTRACT: verify signature\n& deadline MISSIONCONTRACT->MISSIONCONTRACT: check expiry MISSIONCONTRACT->MISSIONCONTRACT: check challenge\nlength MISSIONCONTRACT->MISSIONCONTRACT: State.Completed MISSIONCONTRACT->MISSIONCONTRACT: emit Completed MISSIONCONTRACT-->POMPCONTRACT: (void) POMPCONTRACT-->BROWSER: (hash, wait) deactivate BROWSER loop poll BROWSER->POMPCONTRACT: wait (1) POMPCONTRACT-->BROWSER: (receipt) BROWSER->BROWSER: parse log BROWSER->FIREBASE: Trigger cloudFunction FIREBASE->VERIFIER: Notify VERIFIER end autonumber "[0]" == Verify Mission == VERIFIER->BROWSER: fetch website BROWSER->POMPCONTRACT: query past 100 events (VERIFIED) POMPCONTRACT-->BROWSER: (VERIFIED) VERIFIER->VERIFIER: Lookup\ncode_challenge BROWSER->POMPCONTRACT: missionById POMPCONTRACT-->BROWSER: (mission) BROWSER->VERIFIER: mission details group Submit [verifyWithSig] BROWSER->NEXTAPI: createVerifyTypedData\n(profileId, challenge) activate BROWSER NEXTAPI->POMPCONTRACT: getSigNonce and\nmissionModuleAddress POMPCONTRACT->MISSIONCONTRACT: request MISSIONCONTRACT-->POMPCONTRACT: response POMPCONTRACT-->NEXTAPI: (sigNonce, address) NEXTAPI->NEXTAPI: getDeadline NEXTAPI-->BROWSER: (verifyWithSigTypedData) BROWSER->WALLET: sign (eip-712) deactivate BROWSER WALLET->PLAYER: request signing PLAYER-->WALLET: (signature) WALLET-->BROWSER: (signature) BROWSER->WALLET: writeAsync\n(verifyWithSig) WALLET->PLAYER: send transaction PLAYER->WALLET: confirm WALLET->BROWSER: confirm BROWSER->POMPCONTRACT: verifyWithSig\n(profileId, challenge, signature, deadline, msg.sender) activate BROWSER POMPCONTRACT->POMPCONTRACT: verify VERIFIER Role POMPCONTRACT->MISSIONCONTRACT: verifyWithSig MISSIONCONTRACT->MISSIONCONTRACT: verify signature\n& deadline MISSIONCONTRACT->MISSIONCONTRACT: check challenge\nlength MISSIONCONTRACT->MISSIONCONTRACT: verify challenge MISSIONCONTRACT->MISSIONNFT: safeTransfer MISSIONNFT-->MISSIONCONTRACT: transferTo\nPLAYER WALLET MISSIONCONTRACT->MISSIONCONTRACT: State.Verified MISSIONCONTRACT->MISSIONCONTRACT: emit Verified MISSIONCONTRACT-->POMPCONTRACT: (void) POMPCONTRACT-->BROWSER: (hash, wait) deactivate BROWSER loop poll BROWSER->POMPCONTRACT: wait (1) POMPCONTRACT-->BROWSER: (receipt) BROWSER->BROWSER: parse log BROWSER->NEXTAPI: GET /api/revalidate-profile NEXTAPI->NEXTAPI: revalidate\n/a/[handle] NEXTAPI-->BROWSER: (void) end end autonumber "[0]" == Fail Mission == VERIFIER->BROWSER: fetch website BROWSER->BROWSER: Browse mission BROWSER->BROWSER: 1.Input challenge\n2.Input reason BROWSER->NEXTAPI: createFailTypedData\n(profileId, challenge, reason) activate BROWSER NEXTAPI->POMPCONTRACT: getSigNonce and\nmissionModuleAddress POMPCONTRACT->MISSIONCONTRACT: request MISSIONCONTRACT-->POMPCONTRACT: response POMPCONTRACT-->NEXTAPI: (sigNonce, address) NEXTAPI->NEXTAPI: getDeadline NEXTAPI-->BROWSER: (failWithSigTypedData) BROWSER->WALLET: sign (eip-712) deactivate BROWSER WALLET->PLAYER: request signing PLAYER-->WALLET: (signature) WALLET-->BROWSER: (signature) BROWSER->WALLET: writeAsync\n(failWithSig) WALLET->PLAYER: send transaction PLAYER->WALLET: confirm WALLET->BROWSER: confirm BROWSER->POMPCONTRACT: failWithSig\n(profileId, challenge, reason,\nsignature, deadline, msg.sender) activate BROWSER POMPCONTRACT->POMPCONTRACT: verify VERIFIER Role POMPCONTRACT->MISSIONCONTRACT: failWithSig MISSIONCONTRACT->MISSIONCONTRACT: verify signature\n& deadline MISSIONCONTRACT->MISSIONCONTRACT: verify challenge MISSIONCONTRACT->MISSIONNFT: _burn (tokenId) MISSIONNFT->MISSIONNFT: _resetTokenRoyalty (tokenId) MISSIONNFT-->MISSIONCONTRACT: (void) MISSIONCONTRACT->MISSIONCONTRACT: State.Failed MISSIONCONTRACT->MISSIONCONTRACT: emit Failed MISSIONCONTRACT-->POMPCONTRACT: (void) POMPCONTRACT-->BROWSER: (hash, wait) deactivate BROWSER loop poll BROWSER->POMPCONTRACT: wait (1) POMPCONTRACT-->BROWSER: (receipt) BROWSER->BROWSER: parse log end == Batch Verify (CLI-only) == VERIFIER->POMPCONTRACT: batchVerifyWithSig (profileIds, challenges) activate POMPCONTRACT POMPCONTRACT->MISSIONCONTRACT: batchVerify\n(profileIds, challenges, msg.sender) MISSIONCONTRACT->MISSIONCONTRACT: verify signature\n& deadline loop validate-challenges MISSIONCONTRACT->MISSIONCONTRACT: isValidChallenges\n(43-length) MISSIONCONTRACT->MISSIONCONTRACT: NotFound MISSIONCONTRACT->MISSIONCONTRACT: NotVerifier MISSIONCONTRACT->MISSIONCONTRACT: NotVerifiable MISSIONCONTRACT->MISSIONCONTRACT: NotMatched end MISSIONCONTRACT->MISSIONNFT: oneToManyTransfer\n(ownerIds, tokenIds) MISSIONNFT-->MISSIONCONTRACT: (void) MISSIONCONTRACT->MISSIONCONTRACT: State.Verified MISSIONCONTRACT->MISSIONCONTRACT: emit BatchVerified MISSIONCONTRACT-->POMPCONTRACT: (void) POMPCONTRACT-->VERIFIER: (txReceipt) deactivate POMPCONTRACT @enduml ```