### Install Dependencies Source: https://docs.galxe.com/loyalty-points/getting-started/quick-start Install project dependencies using Forge. ```bash forge install ``` -------------------------------- ### Install SDK Dependencies Source: https://docs.galxe.com/identity/tutorials/simple-workflow Install the necessary SDK and ethers library for your Node.js project. ```bash npm install @galxe-identity-protocol/sdk ethers ``` -------------------------------- ### Install SDK with npm Source: https://docs.galxe.com/identity/sdk Install the Galxe Identity Protocol SDK using npm. This is the standard package manager for Node.js. ```bash npm install @galxe-identity-protocol/sdk ``` -------------------------------- ### API Headers Example Source: https://docs.galxe.com/quest/credential-api/rest-cred/single-config Example of authorization headers for an API request. ```json `Authorization`: `Bearer YOUR_API_KEY` ``` -------------------------------- ### Mint Loyalty Points Example Source: https://docs.galxe.com/loyalty-points/contracts/loyalty-point Example of how to call the mint function to issue loyalty points to a user's address. ```solidity loyaltyPoint.mint(userAddress, 1000); // Mint 1000 points to userAddress ``` -------------------------------- ### API Response Example Source: https://docs.galxe.com/quest/credential-api/rest-cred/single-config Example of a JSON response from an API, indicating whitelist status and balance. ```json { "isWhitelisted": true, "balance": 1000 } ``` -------------------------------- ### Correct Preflight Response Example Source: https://docs.galxe.com/quest/credential-api/overview/cross-domain-check An example of a correct server response to a preflight request, confirming the origin and allowed methods. ```http HTTP/1.1 204 No Content access-control-allow-origin: https://dashboard.galxe.com access-control-allow-methods: POST,GET,OPTIONS ``` -------------------------------- ### GET Request Endpoint Example Source: https://docs.galxe.com/quest/credential-api/rest-cred/single-config Example of an endpoint URL for a GET request to check user status. ```plaintext https://api.example.com/check-user?wallet=$address ``` -------------------------------- ### Install SDK with Yarn Source: https://docs.galxe.com/identity/sdk Install the Galxe Identity Protocol SDK using Yarn. Yarn is another popular package manager for Node.js. ```bash yarn add @galxe-identity-protocol/sdk ``` -------------------------------- ### POST Request Body Example Source: https://docs.galxe.com/quest/credential-api/rest-cred/single-config Example of a JSON body for a POST request, including a user address. ```json { "check_user_address": "$address" } ``` -------------------------------- ### Setup Issuer and Dependencies Source: https://docs.galxe.com/identity/tutorials/simple-workflow Import necessary SDK modules and ethers. Initialize the Ethereum provider and define the dummy issuer's EVM address. This setup is for demonstration purposes and should not be used in production. ```typescript import { prepare, credential, evm, credType, errors, user, issuer, babyzk, utils, statement, claimType, babyzkTypes, } from "@galxe-identity-protocol/sdk"; import { ethers } from "ethers"; // conviniently unwrap the result of a function call by throwing an error if the result is an error. const unwrap = errors.unwrap; // Use cloudflare's free open rpc in this example. const MAINNET_RPC = "https://cloudflare-eth.com"; const provider = new ethers.JsonRpcProvider(MAINNET_RPC); // This is a dummy issuer's EVM address that has been registered on mainnet. // Because it authroize the private key that is public to everyone, // it should not be used in production! const dummyIssuerEvmAddr = "0x15f4a32c40152a0f48E61B7aed455702D1Ea725e"; ``` -------------------------------- ### GraphQL Query Example Source: https://docs.galxe.com/quest/credential-api/graphql-cred/introduction This is an example of a GraphQL query to fetch user information, including whitelisting status and balance. Ensure your endpoint supports this structure. ```graphql query info($address: String!) { user(address: $address) { isWhitelisted balance } } ``` -------------------------------- ### Example Header for Loyalty Points Credential Source: https://docs.galxe.com/identity/specification/credential-format Specific example of a credential header for loyalty points, showing version, type, context ID, and holder ID. ```json "header": { "version": "1", "type": "2", "context": "0xdeadbeef..", "id": "123123" } ``` -------------------------------- ### GraphQL Input Query Example Source: https://docs.galxe.com/quest/credential-api/graphql-cred/single-config This is an example of a GraphQL query to fetch token balance for a given address. The query uses a variable `$address`. ```graphql query info($address: String!) { tokenBalance(address: $address) { balance } } ``` -------------------------------- ### Burn Loyalty Points Example Source: https://docs.galxe.com/loyalty-points/contracts/loyalty-point Example of how to call the burn function to remove loyalty points from a user's address. ```solidity loyaltyPoint.burn(userAddress, 500); // Burn 500 points from userAddress ``` -------------------------------- ### Preflight Request Response Example Source: https://docs.galxe.com/quest/credential-api/overview/cross-domain-check Example of a server response to a preflight request, indicating success (204 No Content) and confirming CORS configuration. ```http HTTP/1.1 204 No Content access-control-allow-origin: * access-control-allow-methods: GET, POST,OPTIONS ``` -------------------------------- ### Install SDK with pnpm Source: https://docs.galxe.com/identity/sdk Install the Galxe Identity Protocol SDK using pnpm. pnpm is an alternative package manager for Node.js that offers efficient package management. ```bash pnpm add @galxe-identity-protocol/sdk ``` -------------------------------- ### Galxe Access Token Detail Response Example Source: https://docs.galxe.com/galxe-id/galxe-id-integration/galxe-id-oauth Example JSON response when retrieving access token details. This includes the client ID, expiration timestamp, and granted scopes. ```json { "client_id": "client_id", "expires_at": "2022-08-31 16:00:22.666401 +0800 CST", "scope": "twitter discord" } ``` -------------------------------- ### Galxe OAuth Token Response Example Source: https://docs.galxe.com/galxe-id/galxe-id-integration/galxe-id-oauth Example JSON response when successfully obtaining an access token. This includes the access token, its expiration time, refresh token, and scope. ```json { "access_token": "OTJLYTIWNMQTYJY1ZC0ZOGQ2LTGYMDITNWQXZWJKNTA4YZAA", "expires_in": 86400, "refresh_token": "NGM5OWUXNDKTNTEZOC01NZBMLWEXMGUTMDUYZGJMNZI3YME0", "scope": "Twitter", "token_type": "Bearer" } ``` -------------------------------- ### Galxe Refresh Token Response Example Source: https://docs.galxe.com/galxe-id/galxe-id-integration/galxe-id-oauth Example JSON response when successfully refreshing an access token. This provides a new access token and potentially a new refresh token. ```json { "access_token": "NTLMMJKYMMQTZJZJYI0ZZGFLLWE5NZMTMZAZMDY3YWMWNMI4", "expires_in": 86400, "refresh_token": "NGQXZGVJZDCTNTQ4YY01NTEZLTHMNTMTYJZHMWZIYJUZMJE3", "scope": "Twitter Discord", "token_type": "Bearer" } ``` -------------------------------- ### Example Credential Type Definition Source: https://docs.galxe.com/identity/specification/type-dsl An example demonstrating the usage of the Type DSL to define a credential. It includes a revocability pragma and declarations for user ID, age, email verification status, and owned NFT IDs. ```dsl @revocable(16); user_id:prop<128,p,2>; age:uint<8>; email_verified:bool; owned_nft_ids:prop<32,p,1>[10]; ``` -------------------------------- ### JSON Data Format Example Source: https://docs.galxe.com/quest/credential-api/rest-cred/introduction Galxe exclusively supports JSON for both GET and POST responses. Ensure your API adheres to this format. ```json { "key": "value" } ``` -------------------------------- ### Onboard User with Multiple Credentials Source: https://docs.galxe.com/galxe-integration/guides/user-verification Initiates a user onboarding process by verifying multiple required credentials. Returns 'approved' if all pass, or 'pending' with missing credentials. ```javascript async function onboardUser(userAddress, accessToken) { const requiredCredentials = [ { credentialId: '312969464', description: 'Twitter Follower', required: true }, { credentialId: '312969465', description: 'Discord Member', required: true } ]; const verification = await verifyMultipleCredentials( requiredCredentials.map(r => r.credentialId), userAddress, accessToken ); if (verification.allPassed) { return { status: 'approved', message: 'Welcome! All requirements met.' }; } else { const missing = requiredCredentials.filter(req => !verification.results.passed.some(p => p.credentialId === req.credentialId) ); return { status: 'pending', message: `Please complete: ${missing.map(m => m.description).join(', ')}`, missingCredentials: missing }; } } ``` -------------------------------- ### Update Credential Items using JavaScript (axios) Source: https://docs.galxe.com/quest/credential-api/api-cred/config This JavaScript example uses the axios library to send a GraphQL mutation to update credential items. It includes error handling and logs the success or failure of the operation. Ensure you have axios installed (`npm install axios`). ```javascript const axios = require("axios"); const credId = "123"; const operation = "APPEND"; const items = ["0x123"]; (async () => { try { let result = await axios.post( "https://graphigo-business.prd.galaxy.eco/query", { operationName: "credentialItems", query: ` mutation credentialItems($credId: ID!, $operation: Operation!, $items: [String!]!) { credentialItems(input: { credId: $credId, operation: $operation, items: $items }) { name } } `, variables: { credId: credId, // Ensure it's a string to avoid overflow operation: operation, items: items, }, }, { headers: { "access-token": "access-token-of-yours", }, } ); if (result.status != 200) { throw new Error(result); } else if (result.data.errors && result.data.errors.length > 0) { console.error(result.data.errors); throw new Error(result.data.errors); } else { console.log("Success:", result.data.data.credentialItems); } } catch (error) { console.error("Error:", error); } })(); ``` -------------------------------- ### Usage Example for Creating a Loyalty Point Token Source: https://docs.galxe.com/loyalty-points/contracts/loyalty-point-factory Demonstrates how to call the createLoyaltyPoint function to deploy a new loyalty point token with specified parameters. ```solidity address newLoyaltyPoint = factory.createLoyaltyPoint("Galxe Points", "GP", adminAddress, [minterAddress1, minterAddress2]); ``` -------------------------------- ### Get Quest Status and Timings Source: https://docs.galxe.com/galxe-integration/getting-started/common-patterns GraphQL query to fetch the status, start time, and end time of a quest. Use this to determine if a quest is currently active. ```graphql query QuestStatus($id: ID!) { quest(id: $id) { status startTime endTime } } ``` -------------------------------- ### Get Credential Information Response Source: https://docs.galxe.com/galxe-integration/guides/user-verification Example JSON response for a credential information query, showing details like name, type, item count, and sync status. ```json { "data": { "credential": { "id": "312969464", "name": "Twitter Follower Verification", "description": "Users who follow @galxe on Twitter", "credType": "TWITTER", "credSource": "TWITTER_FOLLOW", "referenceLink": "https://twitter.com/galxe", "itemCount": 150000, "lastUpdate": 1699200000, "syncStatus": "SYNCED", "curatorSpace": { "id": "40", "name": "BNB Chain" }, "chain": "BSC" } } } ``` -------------------------------- ### Deploy Example Loyalty Point Hook Source: https://docs.galxe.com/loyalty-points/getting-started/hook Deploys the `ExampleLoyaltyPointHook` contract using Forge script. This command requires RPC URL and broadcast flags. ```bash forge script script/DeployExampleLoyaltyPointHook.s.sol:DeployExampleLoyaltyPointHook --rpc-url --broadcast ``` -------------------------------- ### ETH Balance Amount Source: https://docs.galxe.com/quest/credential-api/rest-cred/multi-config Retrieves the amount of ETH held on the mainnet. This example demonstrates how to specify dimensions, construct a POST request, and process the response to get the ETH balance. ```APIDOC ## POST /eth_getBalance ### Description Retrieves the amount of ETH held on the mainnet for a given address. ### Method POST ### Endpoint https://mainnet.infura.io/v3/YOUR-API-KEY ### Parameters #### Request Body - **jsonrpc** (string) - Required - The JSON-RPC version. - **method** (string) - Required - The method to call, which is 'eth_getBalance'. - **params** (array) - Required - An array containing the address and block identifier. - **$address** (string) - Required - The Ethereum address to query. - **latest** (string) - Required - The block identifier, typically 'latest'. - **id** (integer) - Required - The request ID. ### Request Example ```json { "jsonrpc": "2.0", "method": "eth_getBalance", "params": [ "$address", "latest" ], "id": 1 } ``` ### Response #### Success Response (200) - **jsonrpc** (string) - The JSON-RPC version. - **id** (integer) - The request ID. - **result** (string) - The ETH balance in hexadecimal format. #### Response Example ```json { "jsonrpc": "2.0", "id": 1, "result": "0x7c2562030800" } ``` ### Expression ```javascript function(resp) { try { let balance = BigInt(resp.result); return { "mainnet_eth_balance": balance }; } catch (error) { return { "mainnet_eth_balance": 0 }; } } ``` ``` -------------------------------- ### Basic Leaderboard Query Source: https://docs.galxe.com/galxe-integration/api-reference/starboard This example demonstrates how to fetch basic information about a starboard and its leaderboard, including user details and follower counts. ```APIDOC ## POST /query ### Description Fetches basic starboard information and leaderboard data. ### Method POST ### Endpoint https://graphigo-business.prd.galaxy.eco/query ### Parameters #### Request Body - **query** (string) - Required - The GraphQL query string. - **variables** (object) - Required - Variables for the GraphQL query. - **id** (ID!) - Required - The ID of the starboard. ### Request Example ```json { "query": "query GetStarboard($id: ID!) { starboard(id: $id) { basicInfo { name type } leaderboard(pagination: { forward: { first: 10 } }) { edges { node { rank { value } xUserProfile { username followersCount } } } } } }", "variables": { "id": "1" } } ``` ### Response #### Success Response (200) - **data** (object) - Contains the query results. - **starboard** (object) - Information about the starboard. - **basicInfo** (object) - Basic details of the starboard. - **name** (string) - The name of the starboard. - **type** (string) - The type of the starboard. - **leaderboard** (object) - Leaderboard data. - **edges** (array) - A list of leaderboard entries. - **node** (object) - A single leaderboard entry. - **rank** (object) - The rank of the user. - **value** (integer) - The rank value. - **xUserProfile** (object) - User profile information. - **username** (string) - The user's username. - **followersCount** (integer) - The number of followers the user has. #### Response Example ```json { "data": { "starboard": { "basicInfo": { "name": "Example Starboard", "type": "example_type" }, "leaderboard": { "edges": [ { "node": { "rank": { "value": 1 }, "xUserProfile": { "username": "user1", "followersCount": 1000 } } } ] } } } } ``` ``` -------------------------------- ### Open Authorization Server Configuration Source: https://docs.galxe.com/quest/credential-api/overview/cross-domain-check Example server configuration for open authorization, allowing all origins and specified methods. ```http access-control-allow-origin: * access-control-allow-methods: GET, POST,OPTIONS ``` -------------------------------- ### POST Request Endpoint Example Source: https://docs.galxe.com/quest/credential-api/rest-cred/single-config Example of an endpoint URL for a POST request to check user status. ```plaintext https://api.example.com/check-user ``` -------------------------------- ### GraphQL API Endpoint Example Source: https://docs.galxe.com/quest/credential-api/graphql-cred/single-config This is an example of a GraphQL API endpoint URL. Ensure your endpoint is correctly formatted. ```plaintext https://api.example.com/query ``` -------------------------------- ### Fetch User Data with cURL Source: https://docs.galxe.com/galxe-id/galxe-id-integration/galxe-id-oauth Demonstrates how to fetch user data using cURL, including specifying scopes. ```bash curl -H "Authorization: Bearer ${ACCESS-TOKEN}" https://api.galxe.com/oauth/api/2/user?scope=Twitter%20Discord ``` -------------------------------- ### Set Private Key Environment Variable Source: https://docs.galxe.com/loyalty-points/getting-started/hook Sets the private key for deployment. Ensure this key has the necessary permissions. ```bash PRIVATE_KEY= ``` -------------------------------- ### GraphQL API Headers Example Source: https://docs.galxe.com/quest/credential-api/graphql-cred/single-config Optional headers can be added to your GraphQL API request. An access token is shown as an example. ```json `access-token`: `YOUR_TOKEN` ``` -------------------------------- ### Clone Loyalty Point Repository Source: https://docs.galxe.com/loyalty-points/getting-started/quick-start Clone the loyalty-point repository and navigate into the directory. ```bash git clone https://github.com/galxe/loyalty-point.git cd loyalty-point ``` -------------------------------- ### Galxe MSU Space - Endpoint Example Source: https://docs.galxe.com/quest/credential-api/graphql-cred/single-config This is the endpoint URL for the Galxe MSU Space example. It is used to query loyalty points. ```plaintext https://graphigo-business.prd.galaxy.eco/query ``` -------------------------------- ### Quest Details Response Example Source: https://docs.galxe.com/galxe-integration/guides/quests An example JSON response for a quest details query, illustrating the structure and types of data returned. ```json { "data": { "quest": { "id": "GChdWUjXX3", "name": "Introduction to Web3!", "type": "Drop", "status": "Active", "description": "Welcome to Module 1-Course 1 of Mission Web3!", "startTime": 1699200000, "endTime": 1699800000, "cap": 10000, "participantsCount": 234163, "loyaltyPoints": 100, "space": { "id": "40", "name": "BNB Chain" }, "chain": "BSC" } } } ``` -------------------------------- ### Compile Contracts Source: https://docs.galxe.com/loyalty-points/getting-started/quick-start Compile the smart contracts using Forge. ```bash forge build ``` -------------------------------- ### Get User Information Source: https://docs.galxe.com/galxe-id/galxe-id-integration/galxe-id-oauth Retrieve user information by making a GET request to the /oauth/api/2/user endpoint with a valid access token and optional scope. ```APIDOC ## GET https://api.galxe.com/oauth/api/2/user ### Description Retrieves user information associated with the provided access token. The scope parameter allows specifying the desired user data. ### Method GET ### Endpoint https://api.galxe.com/oauth/api/2/user ### Parameters #### Header Parameters - **Authorization** (string) - Required - Bearer ${ACCESS-TOKEN} #### Query Parameters - **scope** (string) - Optional - A space-delimited list of scopes of user data that your APP required. If not set, will set to access token related scope by default. ### Request Example ```bash curl -H "Authorization: Bearer ${ACCESS-TOKEN}" https://api.galxe.com/oauth/api/2/user?scope=Twitter%20Discord ``` ### Response #### Success Response (200) - **TwitterUsername** (string) - The username on Twitter. - **TwitterUserID** (string) - The user ID on Twitter. - **DiscordUsername** (string) - The username on Discord. - **DiscordUserID** (string) - The user ID on Discord. #### Response Example ```json { "TwitterUsername": "twitter_username", "TwitterUserID": "twitter_userid", "DiscordUsername": "discord_username", "DiscordUserID": "discord_userid" } ``` ``` -------------------------------- ### GraphQL API Response Example Source: https://docs.galxe.com/quest/credential-api/graphql-cred/single-config The API response must be in JSON format. This example shows a simple JSON response containing a 'balance' field. ```json { "balance":100 } ``` -------------------------------- ### Main Application Flow with Nebra UPA Source: https://docs.galxe.com/identity/tutorials/use-nebra-upa Sets up the UPA client, creates a user identity, issues a credential, generates a zero-knowledge proof, submits the proof to Nebra UPA, and verifies the proof using public signals. ```typescript async function main() { // prepare must be called by the application before any other function. await prepare(); // setup UPA const upaInstanceDescriptor = JSON.parse( fs.readFileSync("upa.instance", "ascii") ); // eslint-disable-next-line turbo/no-undeclared-env-vars const signer = new ethers.Wallet(process.env.NEBRA_SIGNER_PK!, provider); const upaClient = new UpaClient(signer, upaInstanceDescriptor); // The very first step is to create a user with a random identity. // This should be done on user's device and the identity should be stored securely. const u = new user.User(); const evmIdSlice = u.createNewIdentitySlice("evm"); // User's identity commitment is computed based on the secrets of the identity slice. // You can also retrive the identity commitment from the identity slice. const userIdc = user.User.computeIdentityCommitment(evmIdSlice); // let's use a famous Ethereum address in this example. const userEvmAddr = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; // Issuer's process: issuing a credential to the user. const myCred = await issuingProcess(userEvmAddr, userIdc); console.log("Credential is issued successfully."); console.log(myCred.marshal(2)); // User's process: generating a zk proof to prove some statements about the credential. const proof = await proofGenProcess(myCred, u); console.log("Proof is generated successfully.", proof); const circuitIdProofAndInputs: CircuitIdProofAndInputs[] = [ { circuitId: circuidId, proof: Proof.from_snarkjs(proof.proof), inputs: proof.publicSignals.map((x) => BigInt(x)), }, ]; const submissionHandle = await upaClient.submitProofs( circuitIdProofAndInputs ); const submitProofTxReceipt = await upaClient.waitForSubmissionVerified( submissionHandle ); console.log("Proof is submitted successfully.", submitProofTxReceipt); // Now that our proof submission has been verified, we can just verify the // proof using public signals only. await verifyByCallingAggregatedStatefulVerifier(proof.publicSignals); process.exit(0); } main(); ```