Attendify XRPL API library
Project information
Attendify is an API for PoA(proof of attendance system) built on the XRP ledger that can provide easy and secure way to mint and distribute NFTs or verify attendance at a wide range of events and activities happening in real life or online. Few potential uses for it are:
⚫University students can use the system to quickly verify attendance at lectures, seminars or other educational events.
⚫Large events like conferences etc where it can be difficult to keep track of who has attended and who didn't.
⚫Verifying employee showing up at meetings, training sessions etc.
Project was firstly developed during XRPL NFT hackathon.
Features
⚫ Creating new events and batch minting NFTs for it
⚫ Uploading NFT metadata to IPFS
⚫ Checking if it's possible to claim NFTs for particular event
⚫ Requesting claim for NFT from particular event. The new sell offer for NFT that has to be accepted by the user is returned
⚫ Event attendees lookup
⚫ NFT ownership verification
Documentation
Note: for mock calls to these endpoints and example usage see test.js
Attendify.js
⚫ Current version of documentation for Attendify.js is in the docs
folder and was generated by jsdoc. Latest version of docs is hosted here.
REST API endpoints
This API is built using the ExpressJS framework and the XRPL library, it connect to the local Attendify.js class to perform most of the actions.
⚫ GET /api/mint
- Creates new claimable event and premints NFTs for it. You must have at least X XRP in order to use this to handle the reserve requirements for the NFTs and the minting process which uses Tickets, where X is amount of tokens that should be minted multiplied by 2 + additional XRP for feees.
@param {string} walletAddress - Wallet address from user requesting claim
@param {integer} tokenCount - Amount of NFTs that should be created for the event
@param {string} url - Url to Image for event | Preferably this should be stored on IPFS
@param {string} title - Title for event
@param {string} desc - Description of event
@param {string} loc - Location of event
@returns {object} result - An object with details for the claim event that was successfully created
Structure of the example result object:
{ eventId: 0, account: 'rJ7t4Ei9Q2gs3uZoSLaVajE771Wt9GuuxR', owner: 'rJnCJZZXSSnuDi9YVgrAatVqSvktTeXr5r', URI: 'https://ipfs.io/ipfs/QmWveeBaaPQJhREN523qG5M3ciVmLA6Z271dA1qasVDixw', title: 'test_title', claimable: 3 }
Example request http://localhost:4000/api/mint?walletAddress=rpHJL8bRW81shYm3LwwsXovABps6SM51RS&tokenCount=5&url=ipfs://QmQDDD1cNgnyhPC4pBLZKhVeu12oyfCAJoWr1Qc1QgbkPN&title=test_title&desc=test_description&loc=Warsaw
⚫ GET /api/claim
- Checks if user is eligible for NFT claim or creates new offer that allows for claiming NFT for specific event. Endpoint returns response with sellOfferID that has to be accepted by user afterwards.
@param {string} walletAddress - The wallet address of the user trying to claim
@param {integer} type - The type of claim (1 for checking claim status and metadata, 2 for claiming)
@param {string} minter - The minter address of the event
@param {string} eventId - The ID of the event
@returns {object} result - An object with the event metadata and offer for NFT
Possible responses
-`404` - Event with specified ID does not exist
-`claimed` - The NFT for specified event was already claimed by this user
-`empty` - All NFTs for this particular event were already claimed
-`success` - If `onlyCheckStatus` parameter was true it indicated that current parameters for selected event were sent
-`transferred` - Indicates that new sell offer for NFT related to selected event was created successfully and details were sent to user
Example request http://localhost:4000/api/claim?walletAddress=rpHJL8bRW81shYm3LwwsXovABps6SM51RS&type=2&minter=rMBU1wwAJZZz36YBNxug7YYHKeC5k3vqfG&eventId=0
⚫ GET /api/startVerification
- Starts ownership verification process by generating unique ID for user that has to later be included in a Memo of signed tx. Save the ID returned from this endpoint you're gonna need it for the api/verifyOwnership
to finalize verification process. In case of forgetting or losing this Id you can always generate a new one by calling this endpoint again.
@param {string} walletAddress - Wallet address from user requesting verification
@returns {object} result - An object with generated Memo ID string
File acceptOffer.js
contains example of accepting NFT offer that was created during previous step.
Run this file locally with 2 arguments just like the example below to generate signed tx blob
-
The first argument is seed for the user wallet
-
The second argument should be NFT offer ID returned from
api/mint
endpointnode .\acceptOffer.js sEdVMJSLjuTAjaSeeZ6TEkpUWuTS83j 80517CC6087108B777710DFD0C48B6CB66A43947A96CA4C4B145574E27E9749A
Example request http://localhost:4000/api/startVerification?walletAddress=raY33uxEbZFg7YS1ofFRioeENLsVdCgpC5
⚫ GET /api/verifyOwnership
- Verifies whether or not user owns NFT with provided id for particular event from minter
account.
@param {string} walletAddress - Wallet address from user requesting verification
@param {string} signature - Signature that should be signed by the same account as walletAddress. This could be done either using XUMM or sign
function from xrpl library. The mock transaction from signature has to contain memo with ID generated for walletAddress in api/startVerification
endpoint. See mock transaction JSON below or test.js for example implementation of this
@param {string} minter - The minter address of the event
@param {string} eventId - The ID of the event
@returns {object} result - An object with the verification result as a boolean
{ "Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", "TransactionType": "AccountSet", "Fee": "12", "Sequence": 5, "Domain": "6578616D706C652E636F6D", "SetFlag": 5, "MessageKey": "03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB", "Memos": [ { "Memo": { "MemoData": "<ID_string_returned_from_server_and_turned_hex_using_convertStringToHex_from_xrpl.js>" } } ] }
File signature.js
contains example of local signature generation required for the next verification step.
Run this file locally with 2 arguments just like the example below to generate signed tx blob
-
The first argument is seed for the user wallet
-
The second argument should be verification ID returned from
api/startVerification
endpointnode .\signature.js sEdVMJSLjuTAjaSeeZ6TEkpUWuTS83j PPrnp3O4FI3Z5VCnMvvsMwzjMCmrtZnUNqWQEqkGXIuGJ7xzpCdhUql3X9SwlP1d1unotJX8FHCMJTgbYUQfa7b1nSVb7FY9wSrWH3NxQIF9py1MXfOGGiZyjM6S4WuxhxK1Ru499u9jhnZ3vhifyRPVYFytDD2YUsjqG7F3ojWkVC4VoOEHP4uuztfb2k0ZueCIP1tfbgoAXEuU5DxoSLAWx9kP3b7nKuOqV6lvlbKWGzCI5xE1YG5ExTkowk0M
Example request http://localhost:4000/api/verifyOwnership?walletAddress=raY33uxEbZFg7YS1ofFRioeENLsVdCgpC5&signature=120003240000000520210000000568400000000000000C722103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7321ED57D41105FC480545763677D2100C8949324A97811FE5CB45594B5E73991BBF927440DC49BE4996DFF6CF55D61C7689CF212CCDE1A8F183A30516CDBE8117947C3CD561DAFCFC970504A564C7C9E948F9AC67215032A66A17CB19E6C0DD4684F4D70A770B6578616D706C652E636F6D81143CBB7B1E0212681492733BDA77986A6A7C4C2B4AF9EA7DC13F6139506637714F667157633337535A65413166634B6F67505A6A3334626E4D6D4F4A61766A7A423933306E364847767276546B78596C6E347653645372366E35413067696E6D314467686A53306D30355446743745357868376C67377374736D6C564E6A50636F454B55656F306438415079706C54666C3767516965347833734F52707559654449683955424F4E4B6667784D6F4164777246644578714E796130584852573358714C36705954507667655071707670536946315055775567775536303441533545416267517A7A6F5545575032796A557164544E306D4D593152484172385A56364B734B4C7A4C6E58467966553142594B4B36637539787564E1F1&minter=raY33uxEbZFg7YS1ofFRioeENLsVdCgpC5&eventId=0
⚫ GET /api/attendees
- Looks up attendees for event with specific id with NFTs create by minter address.
@param {string} minter - The minter address of the event
@param {string} eventId - The ID of the event
@returns {object} result - An object with the list of attendees
Example request http://localhost:4000/api/attendees?minter=raY33uxEbZFg7YS1ofFRioeENLsVdCgpC5&eventId=0
ToDo
⚫ Whitelist system
⚫ Configuration: e.g. choosing whether or not NFTs are soulbound
⚫ If called again by the same user the claim endpoint should check if sell offer that wasn't accepted exists and it should be returned instead of showing that NFT was claimed
⚫ Checking whether or not deadline for claiming NFTs has passed
⚫ Integration with updated UI and XUMM wallet
How to setup
⚫execute npm i
in CLI
⚫copy .env.example content to .env file and fill with your data and API keys from INFURA dashboard. Here's a guide showcasing how you can quickly get these keys.
⚫execute npm run start
in CLI to start the server
⚫execute npm run test
to start test process