Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Open Campus, also known as EDU Chain, is the first Layer 3 (L3) blockchain built specifically for the education industry. It aims to leverage the traditional educational landscape by bringing it on-chain, creating a secure and transparent ecosystem for all educational activities.
Educational Blockchain: The first of its kind L3 blockchain tailored for educational purposes.
Learn-to-Earn Ecosystem: A vibrant platform that links learning with earning, providing real-world value to educational achievements.
Transparency and Security: Blockchain technology ensures that all educational records and transactions are secure, immutable, and transparent.
Trackable Learning Journey: Every educational milestone and achievement is recorded on the blockchain, making it easy to track and verify progress.
:::note Please note that this section is under active development. :::
Bridges are a way to connect two different blockchains. They are a special type of smart contract that allows you to lock up tokens on one blockchain and mint the same amount of tokens on another blockchain. This is a very useful feature, as it allows you to transfer tokens between different blockchains. For example, you can transfer tokens from the Ethereum blockchain to the Binance Smart Chain (BSC) blockchain.
import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
The Open Campus block explorer provides a comprehensive and user-friendly interface for monitoring and analyzing network activities. It is designed to offer key insights and information beneficial for both regular users and developers. Features of the Open Campus block explorer include:
Address Balances: Check the balance of any address on the network.
Blockchain technology, often likened to a digital ledger, securely records data in encrypted blocks distributed across a decentralized network. Each block in the chain not only contains a record of new transactions but also carries information from the preceding block. However, due to blockchain's sequential structure, the associated data is dispersed across numerous blocks without an inherent system for identifying or extracting specific, higher-level data.
Blockchain indexing steps in to address this. It allows users to efficiently search and filter through blockchain data, akin to how one might use Google, Bing, or other search engines to find information on the internet.
Blockchain oracles are third-party services or agents that provide smart contracts with external information and serve as bridges between blockchains and the external world. Because blockchains cannot access external data (outside of their network) due to their secure and deterministic nature, oracles are used to fetch, verify, and relay real-world data to smart contracts in a way that's trustworthy.
import TitleComponent from "@site/src/components/TitleComponent";
Wallet as a Service (WaaS) is essentially a modern solution for managing digital assets, tailored for businesses and institutions. It's like having a digital wallet, but with advanced features and security designed for professional use.
At its core, WaaS provides a secure and scalable way to handle cryptocurrencies and other digital assets. It's designed to be flexible, catering to the needs of various businesses, regardless of their size.
In a standard Ethereum transaction, an ethereum user signs and sends the transaction themselves. This user controls the private key to an externally owned account (EOA) which they can use to sign a transaction and prove they have the right to spend the balance associated with that account address. For each transaction a user sends, there is an associated transaction fee, known as gas. Since Ethereum executes computation, each unit of computation has an associated gas cost, which deters malicious actors from overloading the network by requiring them to pay heavily for a potential attack. This is excellent news for Ethereum's security and helps keep the network consistent under load, but it comes at a hidden cost for onboarding new users.
Indexing data within a decentralized infrastructure like blockchain presents several obstacles:
Absence of a Standard Query Language: Blockchain's immutable nature complicates direct data reading, as it lacks a built-in query language similar to SQL in traditional databases. To access even basic information such as a user's transaction history, one would have to examine each block individually.
Complexities in Data Retrieval: The node structure of blockchains, particularly those akin to Ethereum, complicates data retrieval. Historical records are typically spread across various events and stored in separate sections of a node. Limited access to these events in some public nodes can significantly slow down the query process.
Limitations of Existing APIs: The APIs currently available are often restricted to basic queries. These include range queries (such as records from a specific timeframe or a certain number of transactions) and top-k queries (which rank different data points relatively). This limitation hinders the ability to conduct more complex data analyses or searches.
One of the most promising solutions to the challenges of indexing blockchain data is the use of subgraphs. Subgraphs are essentially predefined data structures that are designed to efficiently index and query data from a blockchain.
Subgraphs are open-source APIs that allow developers to extract data from a blockchain and store it in a structured format. They are designed to be flexible, allowing developers to define the data they want to extract and how they want to store it. This flexibility enables subgraphs to be used for a wide range of applications, from simple data retrieval to more complex data analysis.
Customized Data Views: Developers can create subgraphs tailored to their specific needs, focusing on the particular data they're interested in.
Real-time Data Updates: Subgraphs can update their indexed data in real-time with each new block on the blockchain, ensuring up-to-date information.
Decentralized and Open: Like blockchains, subgraphs can be hosted in a decentralized manner, promoting transparency and accessibility.
Read more about Goldsky Indexers below!
import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
Oracles provide price feeds, enabling DeFi platforms to calculate token values, manage collateral, and execute liquidations. By sourcing data from various exchanges and financial platforms, oracles contribute to the robustness of DeFi applications.
Blockchain-based gaming and betting platforms use oracles to determine the outcomes of events, such as sports matches or random number generation. By connecting to various data sources and verifying results, oracles ensure fair and transparent gaming experiences.
Oracles can be employed in the insurance industry to automate claims processing and underwriting. They can fetch data related to weather conditions, flight delays, or health records, enabling insurers to create parametric insurance products. This reduces fraud and ensures quicker payouts based on predefined triggers.
and much more...
import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
Ease of Use and Security: It strikes a balance between being user-friendly and maintaining high security, ensuring that managing digital assets is straightforward without compromising safety.
Integration with Multiple Blockchains: WaaS allows for seamless connection with various blockchain networks. This means businesses can manage different types of digital assets across different blockchains all in one place.
Key Recovery System: One of the challenges with digital wallets is the risk of losing access keys. WaaS typically includes a system for recovering these keys, adding an extra layer of safety and peace of mind.
Low-Cost Fees: It's designed to be cost-effective, minimizing the expenses associated with digital asset management.
WaaS offers a comprehensive digital wallet solution that addresses the main challenges of modern digital asset management, combining ease of use, security, efficient blockchain integration, a reliable key recovery system, and affordability.
import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
How does a new user start interacting with exciting on-chain applications like DeFi, NFTs, or gaming? They will always need the native token to pay for gas on every network, even if the network has very cheap gas fees like Polygon. This requires the user to open an account at a centralised exchange, go through KYC, and buy crypto using fiat. This can be quite a process, even for the most skilled of degens out there, and it can deter new users from being onboarded to a dApp by increasing the latency between their initial excitement and the time it takes to actually get started. This is where relaying comes in! A relayer can help solve these issues by sending a transaction on behalf of the user.
We allow the user to send a transaction without a native token balance (it turns out relayers can be super nifty in loads of ways, for example, allowing a user who wants to swap a token to pay for the gas using the token being swapped!). Ideally, we would also like to still utilise the excellent security of a user signature, but for the transaction to be sent by a different EOA, one controlled by a relayer, who abstracts gas payment away from the user. This is a very import context shift to understand. We have shifted from a user signing and sending a transaction themselves, to a user signing a standardised message and passing that on to a relayer. This relayer will, first, verify the user's signature for security, and then pass their message along on-chain. Gelato Relay does exactly this by taking a user's message off-chain and subsequently building a meta-transaction which is executed on chain.
A meta transaction is a regular ethereum transaction which contains the actual message to be delivered on-chain to a target contract within itself, hence the term meta. The outer transaction helps facilitate the first on-chain call which is sent by a relayer. The call is forwarded to the target contract using an intermediate smart contract (Gelato Relay), which in turn forwards the call using the inner transaction to deliver the relayed message.
To achieve gasless transactions securely, Gelato Relay makes use of the EIP-712 standard. EIP-712 allows for a standardised way to sign and hash typed structured data. This means the user can sign a message using their wallet without incurring a gas cost or interacting with the chain at all, and this signature can be verified on-chain, by the relayer, facilitating a gasless transaction with security built in. This message will include important information such as the transaction signer address, the target contract address, and the calldata payload used to target a specific function.
import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
Web3Auth is a pluggable wallet infrastructure for Web3 wallets and applications. It streamlines the onboarding of both mainstream and crypto native users in under a minute by providing experiences that they're most comfortable with. With support for all OAuth-based login systems, web & mobile native platforms, Web3Auth provides a seamless onboarding experience for your users
You can follow a quick start guide here
In order to use Web3Auth on Open Campus testnet we will need to adap the network config file to
const chainConfig: {
chainNamespace: "eip155",
chainId: "0xA045C",// Cahin Id 656476 in hex
rpcTarget: "https://rpc.open-campus-codex.gelato.digital",
displayName: "Open Campus Codex",
blockExplorer: "https://opencampus-codex.blockscout.com/",
ticker: "EDU",
tickerName: "EDU",
},Transaction History: View detailed transaction records.
Verified Contracts: Access and review verified smart contract codes.
Smart Contract Code and Execution: Examine the code and execution details of smart contracts.
Network Statistics: Get up-to-date information on network performance.
Mining Information: Monitor mining activities and related statistics.
EDU Chain Mainnet Bridge: For transferring assets from Arbitrum One to the EDU Chain Mainnet.
EDU Chain Testnet Bridge: For transferring assets from Arbitrum Sepolia to the EDU Chain Testnet.
1. EDU Chain Mainnet Bridge
Choose Arbitrum One as the source and EDU Chain Mainnet as the destination.
Input the amount of assets you want to bridge.
Confirm and sign the transaction with your wallet.
2. EDU Chain Testnet Bridge
Choose Arbitrum Sepolia as the source and EDU Chain Testnet as the destination.
Input the amount of assets you want to bridge.
Confirm and sign the transaction with your wallet.
After the transaction is confirmed, the bridged assets will be available in your wallet on the selected EDU Chain network, allowing you to interact with dApps and other network features.
:::note Transaction times can vary based on network congestion and gas fees. Ensure you have enough ETH in your wallet to cover the transaction fees. :::
To integrate your product with the OpenCampus ecosystem, you need to retrieve and associate the OCIDs of your users within your system. The "Connect with OCID" functionality works similarly to "Login with Twitter" or "Login with Google." Our product suite provides a JavaScript SDK that you can integrate into your site, enabling users to log into OCID with a simple button click.
This SDK provides an OAuth/OIDC interface to facilitate integration for our partners.
The SDK includes a JavaScript wrapper for our authentication APIs.
It also provides a set of React components for seamless integration into React applications.
Integration instructions are available in the package README on the public npm site.
The Connect with OCID APIs fully implement the OIDC standard, allowing developers to choose custom integration with our authentication APIs.
We enforce the OIDC Code Flow with PKCE for enhanced security.
A Sandbox environment is available and can be easily activated in the SDK for development purposes.
The Sandbox environment does not require redirect_uri whitelisting, enabling developers to test their integrations before going live.
By default, you will only be able to integrate with the “Sandbox” environment. If you have followed Step 1 here you should already have your Client ID and will be able to whitelist your production domain URI.
If you have not done so, head to https://developers.opencampus.xyz/login and apply for a developer account to retrieve the relevant details and to whitelist your domain URI.
Update: You only need to create one OCID account for both staging and production from https://auth.opencampus.xyz/login
Network Name: EDU Chain
Framework: Arbitrum Orbit Stack
Settlement Layer: Arbitrum
Chain ID: 41923
Currency Symbol: EDU
RPC URL:
WebSocket URL: wss://ws.edu-chain.raas.gelato.cloud
Block Explorer:
Bridges:
🌉
🌉
🌉
Network Name: EDU Chain Testnet
Framework: Arbitrum Orbit Stack
Settlement Layer: Sepolia
Chain ID: 656476
Currency Symbol: EDU
RPC URL:
WebSocket URL: wss://ws.open-campus-codex.gelato.digital
Block Explorer:
Faucet: Request Testnet Funds
DPRC:
EDUchain:
HackQuest:
Reminder
Open Campus Codex and its related documentation are under active development.
To manually add the Open Campus Codex network to your wallet, use the following details:
https://rpc.open-campus-codex.gelato.digital
656476
EDU
To start interacting with the Open Campus Codex Testnet, you'll need to bridge your assets. Bridging assets involves transferring cryptocurrencies from one blockchain (Arbitrum Sepolia) to another (Open Campus Codex). This process expands your asset's utility by enabling its use within the Open Campus ecosystem. Ensure Arbitrum Sepolia is the source and EDU Chain Testnet is the destination for the transaction.
Open Campus Codex provides a development environment that is designed to be familiar to those who have worked with Ethereum. It allows developers to deploy smart contracts using existing Ethereum tools and workflows, ensuring a smooth transition and a user experience characterized by higher throughput and reduced transaction costs.
To learn more about how to deploy your smart contracts to the Codex, refer to our comprehensive guide below.
For support, developers can consult the community on platforms like StackExchange or join the official Discord server.
To acquire testnet tokens for network transactions, utilize the dRPC faucet that distributes testnet ETH. Follow the verification process to receive your tokens.
To ensure fair and equitable access, you need to complete the following verification steps:
dRPC Authorization
Log in or create an account with dRPC. It's fast and free.
Proof-of-Work
This faucet requires mining for free testnet tokens to prevent abuse and spam. Note that the process of "mining" doesn't create new coins; it's just a time-limited method of protection.
Configure your wallet to connect to the Sepolia testnet where you can receive testnet ETH.
Access the dRPC faucet to obtain EDU:
Get additional testnet tokens for your EDUChain testing needs. Visit the following link and follow the instructions:
Another reliable source for testnet tokens, available to assist with testing requirements. Check it out here:
Once you have the EDU, you can proceed with testing and development on the Open Campus network.
This document explains how to automatically write any smart contract using the OpenZeppelin Wizard. The resulting smart contract code can either be integrated with Remix by Clicking the Open in Remix button, or copied to clipboard and pasted in the user's intended IDE.
Navigate to the OpenZeppelin Wizard in your browser. First thing to notice is the Solidity Wizard and Cairo Wizard buttons.
One can choose any of the following tabs to begin creating an out-of-box smart contract code in either Solidity (for EVM chains) or Cairolang (useful for Starknet). These are:
ERC20: for writing an ERC-20 token smart contract
ERC721: for writing an NFT token smart contract
ERC1155: for writing an ERC-1155 token smart contract
Governor: for creating a DAO
Custom: for writing a customized smart contract
For illustration purpose, we will be creating a NFT smart contract. Suppose you wanted to create a Mintable, Burnable ERC721 token and specify an appropriate license for it.
Select the ERC721 tab.
Give your NFT a name and a symbol by filling the Name and Symbol fields.
Use the check-boxes on the left to select features of your token
Put a tick on the Mintable check-box
Put a tick on the Auto Increment Ids check-box, this ensures uniqueness of each minted NFT
Put a tick on the Burnable check-box
Notice that new lines of code are automatically written each time a feature is selected.
With the resulting lines of code, you now have the NFT token contract written in Solidity. As mentioned above, this source code can now be ported to an IDE of your choice or opened directly in Remix.
The below figure depicts the auto-written NFT smart contract code.
Create an account at app.goldsky.com.
Create an API key on the Settings page.
Install the Goldsky CLI:
Log in with the API key created earlier:
Deploy your subgraph in one of four ways:
Access data by querying the endpoints. Use the following command to list all your subgraphs, and open the “GraphQL API” links that get printed in your browser to query your data in the GraphQL playground.
The Privy React SDK is the easiest way to onboard your users to web3 in your React App.
With just nine minutes of setup, you get out-of-the-box support for:
A variety of login methods, including email, phone, wallets, and social
Customizable UIs to progressively onboard your users
Self-custodial embedded wallets and powerful connectors for external wallets
For a Quickstart please visit
When using privy on Open Campus Testnet, please bear in mind that defaultChain and supportedChainshave to be included in the chain config. ``` <PrivyProvider appId="your-privy-app-id" config={{ // Customize Privy's appearance in your app appearance: { theme: 'light', accentColor: '#676FFF', logo: 'https://your-logo-url', }, // Create embedded wallets for users who don't have a wallet embeddedWallets: { createOnLogin: 'users-without-wallets', },
In the realm of blockchain development, especially with decentralized applications (dApps), a significant challenge emerges in the form of limited auto-execution capabilities. Traditionally, smart contracts, despite their advanced functionalities, lack the inherent ability to initiate or call methods automatically. This limitation poses a hurdle in the seamless operation and scalability of blockchain applications.
To address this gap, automation solutions have been developed. These systems are designed to monitor both on-chain and off-chain data sources continuously. They are programmed to recognize specific predefined conditions. Once these conditions are met, the automation system springs into action, executing the necessary transactions without human intervention.
Auto Harvesting in DeFi: In decentralized finance applications, automation can manage yield farming strategies, harvesting rewards automatically when they reach a certain threshold, thereby optimizing the return on investment for users.
Limit Orders in Trading: Automated systems can execute trades when certain price points are hit, mirroring the functionality of limit orders in traditional trading but within a decentralized environment.
Read more about Gelato Web3 functions below!
Welcome to the Developer Support section, your go-to resource for technical assistance and guidance.
Technical Assistance: Expert support for your development queries and challenges.
Documentation: Comprehensive guides and API documentation.
Community Support: Access to a community of experienced Web3 developers.
Browse Documentation: Find quick answers in our detailed documentation.
Submit a Ticket: If you can't find an answer, submit a support ticket.
Community Forums: Engage with the community for diverse perspectives.
Clear Descriptions: Provide detailed descriptions of your issues for quicker resolutions.
Include Code Snippets: Share relevant code snippets to clarify your queries.
Be Patient: Responses may take time due to the volume of inquiries.
We're here to ensure your success in the Web3 ecosystem!
Open Campus Achievements and Badges (OCAs and OCBs) are verifiable digital credentials that allow institutions, educators, and communities to recognize and reward learners in a trusted, portable way. Built on the Open Badges and W3C Verifiable Credentials standards, they provide a unified framework for issuing credentials that can be validated across platforms.
Achievements (OCAs): Formal recognitions such as course completions, certifications, or licenses.
Badges (OCBs): Lightweight, gamified recognitions that highlight participation, skills, or milestones.
Every credential issued through Open Campus is tied to a learner’s Open Campus ID (OCID) or wallet, ensuring that ownership is secure, verifiable, and interoperable
LayerZero is a messaging protocol, not a blockchain. Using smart contracts deployed on each chain, in combination with Decentralized Verifier Networks (DVNs) and Executors, LayerZero enables different blockchains to seamlessly interact with one another.
To start sending omnichain messages with LayerZero, you only need to implement two functions:
_lzSend: This function is used to send a message to a different chain.
With Open Campus Achievements/Badges, developers and issuers can:
Recognize learning with portable, tamper-proof credentials.
Engage communities through badges that encourage participation.
Build trust by issuing credentials that follow global standards.
This guide will help you understand how to issue, integrate, and manage OCAs and OCBs using the Open Campus API.
Collaboration: Share ideas, collaborate on projects, and build together.
Support: Get answers to your queries and help others.
Stay Informed: Keep up with the latest trends and updates in Web3.
Respect: Maintain a respectful and constructive environment.
No Spam: Avoid promotional content unrelated to Web3.
Search First: Check if your question has already been answered.
Register: Sign up to participate in discussions.
Introduce Yourself: Let the community know about your interests and expertise.
Engage: Start discussions, share insights, and provide feedback.
FAQ: Common questions and answers.
Documentation: In-depth guides and tutorials.
Community Guidelines
Join our community today and be a part of the Web3 revolution!
Forum Link
Why Participate?
Guidelines
How to Get Started
Resources

📚 Gelato Web3 Functions



// Custom congif here
defaultChain: openCampusChain,
supportedChains: [openCampusChain],
}}
>
</PrivyProvider>
// OpenCampusChain definition here
import { defineChain } from "viem-15";
const openCampusChain= defineChain ({
id: 656476,
network: "Open Campus Codex",
name: "Open Campus Codext",
nativeCurrency: {
name: "EDU",
symbol: "EDU",
decimals: 18,
},
rpcUrls: {
public: {
http: ["https://rpc.open-campus-codex.gelato.digital"],
},
default: {
http: ["https://rpc.open-campus-codex.gelato.digital"],
},
},
blockExplorers: {
default: {
name: "Block Scout",
url: "https://opencampus-codex.blockscout.com/",
},
},
contracts: {
},
testnet: true,
}),
```_lzReceive: This function is used to receive a message from a different chain.
LayerZero offers Contract Standards that simplify this implementation by providing out of the box message handling, interfaces for custom protocol configurations, and other quality of life improvements:
You should first be familiar with writing and deploying contracts to your desired blockchains. This involves understanding the specific smart contract language and the deployment process for those chains.
A wallet set up and funded for the chains you'll be working with.
:::note This example can be used with any EVM compatible chain. ::: To learn how to deploy your contracts, please refer to the Deploying Contracts section.
To checkout endpoint addresses please refer to the Endpoints section in the layerzero docs.
To connect your contracts, call setPeer and pass the address of your destination contract as a bytes32 value, as well as the destination endpoint ID. If successful, you now should be setup to start sending cross-chain messages!
To go more in depth, please refer to the Getting Started section in the layerzero docs.
curl https://goldsky.com | shgoldsky logincd <your-subgraph-directory>
graph build # Build your subgraph as normal.
goldsky subgraph deploy my-subgraph/1.0.0goldsky subgraph deploy your-subgraph-name/your-version --from-abi <path-to-config-file>goldsky subgraph list_lzSend(
_dstEid, // the destination endpoint id
_payload, // encoded message payload being sent
_options, // message execution options
MessagingFee(msg.value, 0), // the fee in native gas and ZRO token
payable(msg.sender) // refund address in case of failed source message
);function _lzReceive(
Origin calldata _origin, // struct containing srcEid, sender address, and the message nonce
bytes32 _guid, // global message packet identifier
bytes calldata payload, // encoded message being received
address _executor, // the address of who executed the message
bytes calldata _extraData // appended executor data for the call
) internal override {
data = abi.decode(payload, (string)); // your receive logic here
}
At the Credential Subject level
At the Credential Payload Level
This would be an image of the logo for your institute. We recommend a square aspect ratio with no less than 1300px * 1300px in resolution for best visual presentation.
At the Credential Subject Level
This would be an image that best represents the specific achievement represented by this credential. It can be a badge, a trophy, a certificate, a mascot … you name it. But please make sure the image DOES NOT:
Contain personal identification information that was not intended to go public.
Contain visual intellectual properties that you are not legally allowed to use or distribute.
We understand your need to have flexibility to best represent the kind of achievement specific to your program. Our guideline is follow an aspect ratio of 4:3 (for landscape) or 3:4 (for portrait) images as close as possible for the best visual result.
The following list of valid achievement types is taken from OpenBadge 3.0 Standard for Achievement Types.
This section provides step-by-step instructions for running an Orbit node on your local machine.
Latest Docker Image: offchainlabs/nitro-node:v3.2.1-d81324d (You can find the latest image here)
RAM: 8-16 GB
CPU: 2-4 core CPU (e.g., AWS t3.xLarge)
Storage: Depends on the Orbit chain and its traffic over time
The --parent-chain.connection.url argument requires a standard RPC endpoint for an EVM node, whether self-hosted or obtained from a node service provider:
In the Arbitrum Orbit context, the child chain is an L2 or an L3 Orbit chain. The required parameters are chain.info-json and chain.name.
chain.info-json A JSON string that contains required information about the Orbit chain.
chain.name A mandatory flag that needs to match the chain name used in --chain.info-json:
3. AnyTrust Chains For AnyTrust chains, add the following flags to the command or configuration:
Or
For the RPC/websocket protocol, use the following flags:
When running a Docker image, an external volume should be mounted to persist the database across restarts. The mount point inside the Docker image should be /home/user/.arbitrum.
Example:
Ensure that /some/local/dir/arbitrum already exists; otherwise, the directory might be created with root as the owner, and the Docker container won't be able to write to it.
When using the flag --chain.info-json=<Orbit Chain's chain info>, replace <Orbit Chain's chain info> with the specific chain info JSON string of the Orbit chain for which you wish to run the node.
Example:
For more detailed instructions and additional configuration options, please refer to the Arbitrum documentation .
OCID Connect is an authentication protocol that allows users to sign in to third-party applications using their OpenCampus identity. It works similarly to other popular single sign-on (SSO) methods like "Login with Google" or "Login with Twitter”
You can find out more about OCID connect in a separate section
Open Campus Achievements (OCAs) are verifiable digital credentials that represent a learner’s formal accomplishments. They are built on the W3C Verifiable Credentials and Open Badges 3.0 standards, ensuring that they are portable, tamper-proof, and interoperable across platforms.
OCAs are typically used for structured, formal recognitions, such as:
Course completions
Professional certifications
Licenses or qualifications
Assessments or skill validations
Each OCA includes:
Metadata: Name, identifier, description, and achievement type
Issuer details: The institution or developer who granted it
Holder identity: The recipient’s Open Campus ID (OCID)
Credential visuals: Logo of the issuing institution and an achievement image (certificate or badge visual)
When issued, an OCA becomes part of the learner’s Open Campus profile and can be shared or verified by third parties without relying on a central authority.
Open Campus Badges (OCBs) are lightweight digital recognitions designed for flexibility, engagement, and gamification. Like OCAs, they follow the Open Badges 3.0 and W3C Verifiable Credentials standards, making them secure and verifiable — but they’re often used for informal or community-driven recognition.
OCBs are well-suited for:
Community participation (e.g., attending an event, joining a program)
Milestones (e.g., completing a challenge, reaching a streak)
Skill highlights (e.g., contributing to a project, demonstrating teamwork)
Engagement rewards (e.g., gamified achievements within a platform)
Each OCB includes:
Metadata: Badge name, description, and achievement type
Issuer details: The organization or community that granted it
Holder identity: Typically tied to an Open Campus ID (OCID), but can also be issued directly to a wallet address when collectionSymbol = ocbadge
Badges are ideal for driving participation and motivation within learning or community ecosystems, while still maintaining interoperability and verification standards.
The OCID Dashboard is the learner’s control center for their Open Campus ID (OCID). It provides a personal profile where holders can view, manage, and share all the credentials they’ve earned — whether Achievements (OCAs) or Badges (OCBs).
Key functions include:
Viewing issued credentials in one place
Sharing credentials externally for verification
Managing linked wallets and identities
The OCID Dashboard ensures that learners always have full visibility and ownership over their verifiable credentials.
The Open Campus Developer Portal is the central hub for issuers and developers to integrate with the Open Campus ecosystem. It provides all the tools needed to issue, manage, and track digital credentials at scale.
Key features include:
API Key Generation – Obtain staging and production keys for secure credential issuance.
Credential Issuance – Issue Achievements (OCAs) or Badges (OCBs) directly from the portal.
With these tools, issuers can handle both individual recognitions and large-scale credential distribution, while maintaining full control over the lifecycle of every credential.
Once verified, a smart contract or token contract's source code becomes publicly available and verifiable, creating transparency and trust.
There are several ways to verify a contract, programmatically or manually on the UI.
Go the the page
Enter in the contract address you received during deployment. The dropdown will show you several available verification options. Select the one you would like to use and continue.
Solidity (Flattended source code)
Solidity (Standard JSON Input)
Contract Address: The 0x address supplied on contract creation (added above)
Is Yul Contract: Select if the contract is coded in Yul for efficiency.
Include Nightly Builds: Select if you want to show nightly builds.
Compiler: derived from the first line in the contract pragma solidity X.X.X. Use the corresponding compiler version rather than the nightly build.
Include nightly builds. You can choose Yes or No depending on your compiler.
Compiler. Choose the compiler version used to compile your smart contract. If you selected yes for nightly builds, use the compiler version rather than the build.
Standard Input JSON. Upload your Standard Input JSON file. File should follows solidity format and all the sources must be in Literal Content format, not a URL.
Click the Verify & publish button and wait for the response.
To verify contracts please follow the Verifying a Smart Contract guide to learn the different options.
In particular, to be able to verify the contracts programatically we will need following steps:
1- Install @nomiclabs/hardhat-etherscan package:
2- Import into hardhat.config.ts
3- Update hardhat.config.ts following:
4- Verify the contract Once the config is updated, you can verofy the contract with
import relay from '@site/static/img/relay_gelato.png';
Using Gelato Relay, we relay your user's transactions on-chain, enabling secure gasless transactions for an ultra-smooth UX for your app. This allows for a variety of new web3 experiences, as the user can now pay by only signing a message, or their transaction costs can be sponsored by the developer. As long as the gas costs are covered in one of the multiple payment methods that Gelato supports, we handle the rest reliably, quickly and securely.
"node": ">=14.0.0"
Basic JavaScript knowledge.
ethers knowledge
Install the Gelato Relay SDK
At this point, you will need to answer the following questions, which will determine the method to use when calling the Gelato Relay.
Do you require user authentication? When the use-case requires to authenticate the original user, you will need to implement the ERC2771 method where the user will sign the payload, and the original user will be decoded on-chain from the callData replacing msg.sender through _msgSender(), please see additional info here.
What is the funding strategy? When relaying a transaction, the Gelato Nodes are paying the gas fees. There are two different ways of paying the fees back to Gelato. Either creating a 1Balance account and deposit USDC on polygon that will pay for all of the transactions on all EVM chains Gelato is deployed; or transferring back to gelato the fees while the transaction is executing, we call these methods syncFee, more info can be found here, in this latter case, the target contract would need to inherit the "Gelato Relay Context" contracts, so the methods to query and transfer the fee to Gelato are available.
If you require user authentication and you want to pay the transactions with a 1Balance account, the method to use is the sponsoredCallERC2771.
If you require user authentication and you want every transaction to pay for itself, transferring by execution the fees to Gelato, the method to use is the callWithSyncFeeERC2771.
If you don't require user authentication and you want to pay the transactions with a 1Balance account, the method to use is the sponsoredCall.
If you don't require user authentication and you want every transaction to pay for itself, transferring the fees by execution to Gelato, the method to use is the callWithSyncFee.
We will require three simple steps to implement Gelato Relay. Here, we are going to showcase the three steps required to implement the method sponsoredCallERC2771, which is the most used one.
Depending on the method, you must inherit different contracts as they will provide other methods. In this case, we will have to inherit the ERC2771Context. The ERC2771Context provide us with the methods _msgSender() and _msgData() that will allow us to recover the original user sending the transaction.
In your frontend/backend, you would need to import and instantiate the relay class.
This is an example using Gelato's CounterERC2771.sol, which is deployed on these networks.
When submitting your Gelato Relay requests, you'll receive a taskId in response. This taskId allows you to track the status of your request in two primary ways:
WebSocket Subscriptions: This is the recommended and most efficient method. By subscribing via WebSocket, the Gelato backend will automatically push updates for all your tasks to your Relay SDK client. To start receiving these updates, you must register a callback function, which will be triggered every time one of your tasks gets updated. Detailed implementation can be found here.
Polling for Updates: Alternatively, you can periodically query the Gelato task status API for updates. If you're using the Gelato Relay SDK, the getTaskStatus method makes this easy. Detailed implementation can be found here.
DIA token price feeds provide smart contract real-time price information of 3,000+ cryptocurrencies, transparently sourced from 80+ trusted, high-volume DEXs and CEXs.
The feeds facilitate the development of DeFi use cases such as money markets, lending/borrowing, synthetic asset issuance, options, derivatives and futures markets, and many more.
Here is an example of how to retrieve price value from a standard DIA oracle. For the purpose of this example, we will be using the following demo oracle on Ethereum: 0xa935...5856.
Access any DIA oracle smart contract.
Call getValue(pair_name) with pair_name being the full pair name such as BTC/USD. You can use the "Read" section on Etherscan to execute this call.
The response of the call contains four values:
The current asset price in USD with a fix-comma notation of 8 decimals.
the UNIX timestamp of the last update.
Here is an example on how you can integrate DIA's oracle into your smart contract with Solidity:
Find more detailed description of the functions and how to run test in this
DIA has a dedicated Solidity library to facilitate integration of DIA oracles in your own contracts. The library consists of two functions, getPrice and getPriceIfNotOlderThan. You can learn more about the library and how to use it in the .
Gelato's Web3 Functions is a powerful automation system designed to streamline and enhance Web3 operations. Web3 Functions serve as a comprehensive tool, enabling developers to effortlessly set up, manage, and automate their smart contract tasks. Determining your Needs
Off-chain Data or Computation? Sometimes, automation tasks require data that isn't readily available on the blockchain, or they might need computations that are better performed off-chain. In such cases, Typescript Functions should be the choice.
All Checks On-chain? If all the conditions necessary for your automation task can be directly verified on the blockchain, you have the option to select between Typescript Functions, Solidity Functions & Automated Transactions
Achievement
ApprenticeshipCertificate
Assessment
Assignment
AssociateDegree
Award
Badge
BachelorDegree
Certificate
CertificateOfCompletion
Certification
CommunityService
Competency
Course
CoCurricular
Degree
Diploma
DoctoralDegree
Fieldwork
GeneralEducationDevelopment
JourneymanCertificate
LearningProgram
License
Membership
ProfessionalDoctorate
QualityAssuranceCredential
MasterCertificate
MasterDegree
MicroCredential
ResearchDoctorate
SecondarySchoolDiploma
RPC/http
8547
RPC/websocket
8548
Sequencer Feed
9642
EVM Version: Select the correct EVM version if known, otherwise use default.
Enter the Solidity Contract Code: You may need to flatten your solidity code if it utilizes a library or inherits dependencies from another contract. We recommend hardhat or the POA solidity flattener. To flatten your contract using hardhat, see here
Add Contract Libraries: Enter the name and 0x address for any required libraries called in the .sol file. You can add multiple contracts with the "+" button.
Click the Verify and Publish button.
If all goes well, you will see a checkmark next to Code in the code tab, and an additional tab called Read Contract. The contract name will now appear in BlockScout with any transactions related to your contract.

Time Interval Description: Use this trigger to execute tasks at regular intervals, e.g., every 10 minutes or once every 24 hours. It's like setting a straightforward, recurring alarm.
Cron Expressions Description: This offers a more refined control compared to the Time Interval. With cron expressions, you can set tasks to run at specific moments, such as "every Tuesday at 3 PM" or "on the 1st of every month". It gives you precision in task scheduling.
On-Chain Event Description: Ideal for those wanting their tasks to respond dynamically to blockchain activities. Whenever a specified event occurs on the blockchain, this trigger springs your task into action. It's like a vigilant watcher, always ready to act.
Every Block Description: This function operates with the rhythm of the blockchain itself, executing your chosen function each time a new block is created.
Typescript Functions are decentralized cloud functions that work similarly to AWS Lambda or Google Cloud, just for web3. They enable developers to execute on-chain transactions based on arbitrary off-chain data (APIs / subgraphs, etc) & computation. These functions are written in Typescript, stored on IPFS and run by Gelato.
Solidity Functions are crucial for making on-chain tasks automatic and more efficient. They connect set conditions with specific actions in a smart contract, providing a straightforward method to turn user needs into automated processes. Consider them as a set of "if-then" rules: If certain conditions are met on the blockchain, then a specific function gets executed. This level of automation ensures that the decentralized application can operate with minimal manual intervention, providing a seamless user experience.
Automated Transaction ensures that a specific function on the target smart contract gets reliably triggered. When you pre-define the inputs, it means that every time Gelato initiates the function call, it uses consistent, predetermined arguments.
Clone the hardhat-template repo
CD into the folder and install
Update the index.ts in one of the examples
Deploy the Web3 Function to IPFS and create the Task
Result:
Finally, go to the Gelato App, create a new task, decide on the trigger, and input the CID.
The central part of a solidity function is the Checker. A Checker acts as a bridge between conditions and smart contract executions. Its purpose? To check conditions and determine whether a task should be executed by Gelato. Every checker returns two main things:
canExec (Boolean): Indicates if Gelato should execute the task.
execData (Bytes): Contains the data that executors will use during execution.
Once you have deployed your checker, go to the Gelato App, create a new task, decide the trigger, and input the address of the checker contract and the method that does the check.
--parent-chain.connection.url=<Parent chain RPC URL>--chain.info-json=<Orbit Chain's chain info>```sh
--chain.name=<Orbit Chain's name>
```--node.data-availability.enable
--node.data-availability.rest-aggregator.urls=<A list of DAS REST endpoints>--node.data-availability.rest-aggregator.online-url-list=<A URL that returns a list of the DAS REST endpoints>--ws.port=8548
--ws.addr=0.0.0.0
--ws.origins=\*docker run --rm -it -v /some/local/dir/arbitrum:/home/user/.arbitrum -p 0.0.0.0:8547:8547 -p 0.0.0.0:8548:8548 offchainlabs/nitro-node:v2.3.4-b4cc111 --parent-chain.connection.url=<Parent chain RPC URL> --chain.id=<OrbitChainId> --chain.name=<My Arbitrum Orbit Chain> --http.api=net,web3,eth --http.corsdomain=* --http.addr=0.0.0.0 --http.vhosts=* --chain.info-json=<Orbit Chain's chain info> --chain.info-json="[{\"chain-id\":94692861356,\"parent-chain-id\":421614,\"chain-name\":\"My Arbitrum L3 Chain\",\"chain-config\":{\"chainId\":94692861356,\"homesteadBlock\":0,\"daoForkBlock\":null,\"daoForkSupport\":true,\"eip150Block\":0,\"eip150Hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"eip155Block\":0,\"eip158Block\":0,\"byzantiumBlock\":0,\"constantinopleBlock\":0,\"petersburgBlock\":0,\"istanbulBlock\":0,\"muirGlacierBlock\":0,\"berlinBlock\":0,\"londonBlock\":0,\"clique\":{\"period\":0,\"epoch\":0},\"arbitrum\":{\"EnableArbOS\":true,\"AllowDebugPrecompiles\":false,\"DataAvailabilityCommittee\":false,\"InitialArbOSVersion\":10,\"InitialChainOwner\":\"0xAde4000C87923244f0e95b41f0e45aa3C02f1Bb2\",\"GenesisBlockNum\":0}},\"rollup\":{\"bridge\":\"0xde835286442c6446E36992c036EFe261AcD87F6d\",\"inbox\":\"0x0592d3861Ea929B5d108d915c36f64EE69418049\",\"sequencer-inbox\":\"0xf9d77199288f00440Ed0f494Adc0005f362c17b1\",\"rollup\":\"0xF5A42aDA664E7c2dFE9DDa4459B927261BF90E09\",\"validator-utils\":\"0xB11EB62DD2B352886A4530A9106fE427844D515f\",\"validator-wallet-creator\":\"0xEb9885B6c0e117D339F47585cC06a2765AaE2E0b\",\"deployed-at\":1764099}}]"yarn add --dev @nomiclabs/hardhat-etherscanimport "@nomiclabs/hardhat-etherscan"; etherscan: {
apiKey: {
"edu-chain-testnet": "XXXX",
"edu-chain": "XXXX",
},
customChains: [
{
network: "edu-chain-testnet",
chainId: 656476,
urls: {
apiURL: "https://edu-chain-testnet.blockscout.com/api",
browserURL: "https://edu-chain-testnet.blockscout.com",
},
},
{
network: "edu-chain",
chainId: 41923, // Replace with the correct mainnet chain ID if different
urls: {
apiURL: "https://educhain.blockscout.com/api",
browserURL: "https://educhain.blockscout.com",
},
},
],
},npx hardhat verify --network edu-chain YOUR-CONTRACT-ADDRESS YOUR-CONSTRUCTOR-ARGUMENTSyarn add @gelatonetwork/relay-sdkimport {
ERC2771Context
} from "@gelatonetwork/relay-context/contracts/vendor/ERC2771Context.sol";
contract CounterERC2771 is ERC2771Context {
// ERC2771Context: setting the immutable trustedForwarder variable
constructor(address trustedForwarder) ERC2771Context(trustedForwarder) {}
function incrementContext() external {
// Incrementing the counter mapped to the _msgSender!
contextCounter[_msgSender()]++;
// Emitting an event for testing purposes
emit IncrementContextCounter(_msgSender());
}
}import { GelatoRelay, SponsoredCallERC2771Request } from "@gelatonetwork/relay-sdk";
const relay = new GelatoRelay(API_KEY);// Set up on-chain variables, such as target address
const counter = "0x00172f67db60E5fA346e599cdE675f0ca213b47b";
const abi = ["function incrementContext()"];
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = provider.getSigner();
const user = signer.getAddress();
// Generate the target payload
const contract = new ethers.Contract(counter, abi, signer);
const { data } = await contract.incrementContext.populateTransaction();
// Populate a relay request
const request: CallWithERC2771Request = {
chainId: (await provider.getNetwork()).chainId,
target: counter;
data: data;
user: user;
};
// Without a specific API key, the relay request will fail!
// Go to https://relay.gelato.network to get a testnet API key with 1Balance.
// Send a relay request using Gelato Relay!
const relayResponse = await relay.sponsoredCallERC2771(request, provider, apiKey);pragma solidity ^0.8.13;
interface IDIAOracleV2{
function getValue(string memory) external returns (uint128, uint128);
}
contract IntegrationSample{
address immutable ORACLE = 0xa93546947f3015c986695750b8bbEa8e26D65856;
uint128 public latestPrice;
uint128 public timestampOflatestPrice;
function getPriceInfo(string memory key) external {
(latestPrice, timestampOflatestPrice) = IDIAOracleV2(ORACLE).getValue(key);
}
function checkPriceAge(uint128 maxTimePassed) external view returns (bool inTime){
if((block.timestamp - timestampOflatestPrice) < maxTimePassed){
inTime = true;
} else {
inTime = false;
}
}
}git clone web3-functions-hardhat-templatecd web3-functions-hardhat-template && yarn installWeb3Function.onRun(async (context: Web3FunctionContext) => {
const { userArgs, multiChainProvider } = context;
const provider = multiChainProvider.default();
// Retrieve Last oracle update time
const oracleAddress =
(userArgs.oracle as string) ?? "0x71B9B0F6C999CBbB0FeF9c92B80D54e4973214da";
// YOUR CUSTOM LOGIC
.....
// Return if nothing has to be pushed on-chain
return { canExec: false, message: `Coingecko call failed` };
// Return if tx has to be pushed on-chain
return {
canExec: true,
callData: [
{
to: oracleAddress,
data: oracle.interface.encodeFunctionData("updatePrice", [price]),
},
],
};
});npx w3f deploy web3-functions/YOUR-FUNCTION/index.ts$ npx w3f deploy web3-functions/YOUR-FUNCTION/index.ts
✓ Web3Function deployed to ipfs.
✓ CID: QmYMysfAhYYYrdhVytSTiE9phuoT49kMByktXSbVp1aRPx
To create a task that runs your Web3 Function every minute, visit:
> https://beta.app.gelato.network/new-task?cid=QmYMysfAhYYYrdhVytSTiE9phuoT49kMByktXSbVp1aRPx
✨ Done in 3.56s.Bulk issuance: Upload a CSV file to issue credentials to multiple learners at once.
Credential Management – Take direct actions on issued credentials, including:
Revoking credentials when they are no longer valid
Viewing issuance history for audit and verification
Tracking credential status across holders




Staging (Sandbox) OCA/OCB Issuance Endpoint:
Production OCA/OCB Issuance Endpoint
Authorization
Body for OCA (raw JSON)
Arbitrum Orbit is an Optimistic rollup-based framework designed to empower web3 businesses by enabling the creation of custom, use case-specific Layer 2 (L2) or Layer 3 (L3) chains in a purely permissionless way. Orbit leverages the Arbitrum Nitro Tech stack, offering unparalleled scalability, advanced compression, full EVM compatibility, and soon-to-be-released cross-chain interoperability. Essentially, Arbitrum Orbit can be thought of as deployable and configurable instances of the Nitro stack, forming an ecosystem of independent chains.
Customizable Throughput: Orbit chains provide dedicated throughput, ensuring high performance and resource availability tailored to specific dApp requirements.
EVM+ Compatibility: Support for multiple programming languages (Rust, C++, C, and Solidity) through Stylus, enabling flexible and cost-effective smart contract development.
Predictable Gas Costs: Isolated transaction environments ensure stable and predictable gas fees, crucial for business cost forecasting.
Broad Data Availability Options: Flexibility to choose data availability models, including Ethereum Layer 1 or Data Availability Committees (DACs) for off-chain storage.
Robust Security: Leveraging Ethereum's security and the Arbitrum Nitro tech stack ensures a high level of security for Orbit chains.
By choosing Arbitrum Orbit, Open Campus leverages a powerful, flexible, and scalable blockchain solution that meets our unique needs. This partnership enables us to build an innovative educational platform that redefines the Learn-to-Earn model, offering unparalleled benefits to our users.


bob.edu
Body for OCB (raw JSON)
credentialPayload
object
Issuer reference ID is an optional field that is used to uniquely identify the OCA/OCB issued by the issuer. Each issuer reference ID can be only used once by each issuer. Issuance will fail if there is another OCA/OCB with the same issuer reference ID that has been issued by the same issuer before.
Credential Payload is what you would use to represent the credential that you are issuing. We accept the following fields. Some of them are required and some of them are optional. Here we list the specifications for the credential payload based on the OpenBadge standard.
Please refer to the tables below for the explanation of specific fields, including examples how the metadata of Open Campus's verifiable credential should be structured.
There are 2 locations where you should provide your image URI when issuing your credentials. The image in credentialSubject follows the guideline of W3C standard for Achievement type of verifiable credential. The image in credentialPayload allows other platforms (NFT Marketplaces, Block explorers, etc.) to grab your VC image.
credentialPayload
awardedDate
string
Y
Y
2023-09-08T16:00:00.000Z
ISO 8601 Date Format
description
string
Y
credentialSubject
achievement
object
Y
Y
{ … }
see below details
name
string
Y
achievement
identifier
string
Y
Y
a8505caa-8e3a-4c07-aae2-94944c6b52fc
stored on-chain maxLength 50 characters
achievementType
string
Y
credentialPayload
object
holderOcId
string
This is the expected user flow for third party platforms looking to integrate OCAs into their ecosystem. At this moment, OCAs can only be issued to an OCID account, therefore it is important that the OCID Connect portion is set up on your platform before any issuance happens.
We have just launched the OC Developer portal hoping to scale up the capability of self-served integration for developers and partners. Head to to create an OCID if you have not already done so. If you are building on behalf of an organisation, we strongly recommend that you create a separate OCID <organisationName>.edu that will be used to request for production API key.
Once you've done so, prepare the following information and head to and apply for a developer account with your OCID. It will take typically 3-5 working days for review, alternatively you can reach out to @lewlian on telegram to expedite your approval if needed.
A sandbox environment can be activated in the SDK for development purposes. Please find the full guide for Open Campus ID Connect integration
When you have completed the integration on production, you should have a “Connect with OCID” that allows you to:
Create a new OCID
Login and connect an existing OCID
Before you move on to the next segment, it is recommended that you generate two OCID accounts:
Issuer’s OCID: This is the OCID account that will be requesting for Issuer permission and also become the Issuing entity for OCAs later. This should be the OCID that already has access to the developer portal
User’s OCID: This is the OCID account that will be receiving the OCA and view them on the OCID Dashboard.
On a high level, a Sandbox Issuer’s API Key will be needed to issue an OCA/OCB with the sandbox API endpoint provided. To obtain it, please head to and login with the OCID account registered as a developer. Click on "OCA API Keys".
Select "Request staging key" and allow a few minutes for your keys to be generated in the backend.
Once your staging API keys are generated, you should be able to see the two parameters that you need for integration:
Staging API Key
DID String
Authorization
Once your obtained an API Key from the dashboard, you can use your API Key in the HTTP POST header for authorization:
Body Params (JSON)
If you have followed the , holderOcId will refer to the User’s OCID that you generated in the previous segment. If you only have one OCID generated you may also issue an OCA to the issuer’s account.
Sample Body (raw JSON):
If you wish to find out more about the specifications for each of the properties in the body params, please refer to . You will also find the recommended image dimensions for OCAs there.
OCID Dashboard
Once you have successfully issued the OCA to a holder’s OCID, there are two ways that you can view the OCA:
Logging in to the Open Campus ID Dashboard in the sandbox environment using the holder’s account at
View the holder’s public profile at https://id.sandbox.opencampus.xyz/public/credentials?username=<OC_ID>
Body Params (JSON)
For OC Badges, it is largely similar to OC Achievements but you will need to specify collectionSymbol as ocbadge otherwise it will default to OCA issuance. You may also issue OC Badges directly to wallets instead of OCIDs by changing holderOcId to holderAddress
Sample Body for issuance to OCID (raw JSON):
Sample Body for issuance to wallet (raw JSON):
⚠️ For Yuzu x OC Badge Season 3 participating Dapps. Only OC badges issued to wallets are eligible for Yuzu points, please ensure that you are following the body params below for issuance to wallet.
CredentialPayload
For Yuzu x OC Badge Season 3 participating Dapps. Please ensure that name in credentialPayload matches the Badge Name in your badge submission form
In order to ensure that third party integrations are successful and did not deviate too much from the intended flow of how OCAs should be issued, we require teams to do a recording of their integrated flow on the sandbox environment and submit to the Open Campus team via the form below. Please reach out to @kittyvo and @lewlian to escalate your review process.
To promote the sandbox environment to production, you will need:
Request for Issuer’s production API Key
Complete and submit this to the Open Campus team
Once this is approved, you will be informed and able to view your API Key and DID Key for production from the OC Developer Dashboard
Secure your API Key safely, your API Key is tied to your issuer identity and losing your API Key means allowing others to issue Achievements on your behalf.
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
Hardhat is a popular smart contract development frameworks. In this tutorial, we will be using Hardhat to deploy a simple Counter smart contract to the Custom Rollup Testnet. We will explore the basics of creating a Hardhat project with a sample contract and a script to deploy it.
For the full instruction on how to use Hardhat, please refer to the .
Start with creating an npm project by going to an empty folder, running npm init, and following its instructions. You can use another package manager, like yarn, but Hardhat recommends you use npm 7 or later, as it makes installing Hardhat plugins simpler.
POST <https://api.vc.staging.opencampus.xyz/issuer/vc>POST <https://api.vc.opencampus.xyz/issuer/vc>Header: { X-API-KEY: <your api key> }{
"credentialPayload": { ... },
"holderOcId": "bob.edu",
"issuerReferenceId": "tt:1111222333"
}{
"validFrom": "2023-12-10T16:00:00.000Z",
"awardedDate": "2023-12-10T16:00:00.000Z",
"description": "An achievement for achieving outstanding results in mathematics course",
"credentialSubject": {
"name": "John Doe",
"type": "Person",
"email": "[email protected]",
"image": "https://img.freepik.com/premium-vector/gold-medal-with-gold-ribbon-that-says-gold_1134661-43944.jpg",
"profileUrl": "https://mycourse.xyz/profile/johndoe",
"achievement": {
"name": "Gold Medal Achievements",
"identifier": "tt:1111222333",
"description": "Reached 200 points in the intermediate mathematics",
"achievementType": "Achievement",
"attachments": [
{
"url": "<URL_OF_ATTACHMENT>",
"type": "<ENUM_ATTACHMENT_TYPE>",
"title": "<NAME_OF_ATTACHMENT>"
}
]
},
"ext:OC_CUSTOM:custom": {
"ext:OC_CUSTOM:<OC_ID_OF_ISSUER>:key1": "custom value 1",
"ext:OC_CUSTOM:<OC_ID_OF_ISSUER>:key2": "custom value 2"
}
}
}{
"credentialPayload": { ... },
"collectionSymbol": "ocbadge",
"holderOcId": "bob.edu" OR "holderAddress": "0xabcD12345...",
"issuerReferenceId": "tt:1111222333"
}Y
my school certification
Description of the credential
validFrom
string
Y
Y
2023-09-08T16:00:00.000Z
ISO 8601 Date Format
validUntil
string
N
Y
2023-09-08T16:00:00.000Z
ISO 8601 Date Format
image
string
N
Y
https://image.com/img/11111.jpg
Valid http uri. This should be the same as the one in credentialPayload, allowing other platforms to grab your VC image
credentialSubject
object
Y
Y
{ … }
see below details
N
Bob
stored but not exposed to public
string
Y
N
stored but not exposed to public
profileUrl
string
N
Y
https://mycompany.xyz/profiles/public/11223344
this should be users public profile
image
string
N
Y
https://image.com/img/11111.jpg
Valid http uri, this is in accordance to W3C standard for Achievement type
ext:OC_CUSTOM:custom
object
N
Y
{ … }
unspecified blob of custom data
Y
Certificate
see appendix for valid achievement types
name
string
Y
Y
Blockchain Certification
description
string
Y
Y
An introductory blockchain bootcamp class
description of the achievement requirement
attachments
array
N
Y
[ { pdf: “….” , png: “….“ }, { … } ]
no standard for internal objects
To create the sample project, run npx hardhat init in your project folder:
Press <ENTER> choose javascript, typescript or empty project
Press <ENTER> to set the project root
Press <ENTER> again to accept addition of .gitignore
Press <ENTER> to install hardhat @nomicfoundation/hardhat-toolbox
Create the .env file in your project root folder and add the following line:
Populate the .env file with your private key. You can get your private key from Metamask. See the section below on how to get your private key from Metamask.
:::warning Do not commit your private key to a public repository!
Verify that your .gitignore file contains .env to prevent your private key from being committed to a public repository. :::
Open the hardhat.config.js file and paste the code below:
:::info Note: The existing smart contract code that comes with the sample project is a Lock.sol contract. Feel free to delete it or leave it. :::
Create a new file, in the contracts folder, named Counter.sol:
Copy the below code and paste it in the Counter.sol contract code:
Delete the content of the scripts/deploy.js file and add the code below:
Install dotenv package: npm install dotenv
Compile your contract code (i.e., go back to the project root in the CLI),
Run the deploy script:
{
"validFrom": "2023-12-10T16:00:00.000Z",
"awardedDate": "2023-12-10T16:00:00.000Z",
"description": "Season 3 Badge from XXXSwap",
"credentialSubject": {
"type": "Person",
"image": "https://img.freepik.com/premium-vector/gold-medal-with-gold-ribbon-that-says-gold_1134661-43944.jpg",
"profileUrl": "https://mycourse.xyz/profile/johndoe",
"achievement": {
"name": "LiquidityKing",
"identifier": "tt:1111222333",
"description": "transacting more than $100 in value on Sailfish",
"achievementType": "Badge"
},
}
}npx hardhat compilenpx hardhat run scripts/deploy.js --network edu-chain //For testnet
npx hardhat run scripts/deploy.js --network edu-chain-testnet //For mainnetACCOUNT_PRIVATE_KEY='my private key'require("dotenv").config();
require("@nomicfoundation/hardhat-toolbox");
module.exports = {
solidity: "0.8.19",
paths: {
artifacts: "./src",
},
networks: {
"edu-chain-testnet": {
// Testnet configuration
url: `https://rpc.open-campus-codex.gelato.digital`,
accounts: [process.env.ACCOUNT_PRIVATE_KEY],
},
"edu-chain": {
// Mainnet configuration
url: `https://rpc.edu-chain.raas.gelato.cloud`,
accounts: [process.env.ACCOUNT_PRIVATE_KEY],
},
},
etherscan: {
apiKey: {
"edu-chain-testnet": "XXXX",
"edu-chain": "XXXX",
},
customChains: [
{
network: "edu-chain-testnet",
chainId: 656476,
urls: {
apiURL: "https://edu-chain-testnet.blockscout.com/api",
browserURL: "https://edu-chain-testnet.blockscout.com",
},
},
{
network: "edu-chain",
chainId: 41923, // Replace with the correct mainnet chain ID if different
urls: {
apiURL: "https://educhain.blockscout.com/api",
browserURL: "https://educhain.blockscout.com",
},
},
],
},
};import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import * as dotenv from "dotenv";
dotenv.config({ path: __dirname + "/.env" });
const ACCOUNT_PRIVATE_KEY = process.env.ACCOUNT_PRIVATE_KEY || "";
const config: HardhatUserConfig = {
solidity: "0.8.19",
paths: {
artifacts: "./src",
},
networks: {
"edu-chain-testnet": {
// Testnet configuration
url: `https://rpc.open-campus-codex.gelato.digital`,
accounts: [ACCOUNT_PRIVATE_KEY],
},
"edu-chain": {
// Mainnet configuration
url: `https://rpc.edu-chain.raas.gelato.cloud`,
accounts: [ACCOUNT_PRIVATE_KEY],
},
},
etherscan: {
apiKey: {
"edu-chain-testnet": "XXXX",
"edu-chain": "XXXX",
},
customChains: [
{
network: "edu-chain-testnet",
chainId: 656476,
urls: {
apiURL: "https://edu-chain-testnet.blockscout.com/api",
browserURL: "https://edu-chain-testnet.blockscout.com",
},
},
{
network: "edu-chain",
chainId: 41923,
urls: {
apiURL: "https://educhain.blockscout.com/api",
browserURL: "https://educhain.blockscout.com",
},
},
],
},
};
export default config;touch contracts/Counter.sol//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract Counter {
uint256 currentCount = 0;
function increment() public {
currentCount = currentCount + 1;
}
function retrieve() public view returns (uint256){
return currentCount;
}
}const hre = require("hardhat");
async function main() {
const deployedContract = await hre.ethers.deployContract("Counter");
await deployedContract.waitForDeployment();
console.log(`Counter contract deployed to ${deployedContract.target}`);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});Then replace with the production issuance endpoint
credentialPayload
object
holderOcId
string
bob.edu
credentialPayload
object






POST <https://api.vc.opencampus.xyz/issuer/vc>Header: { X-API-KEY: <your api key> }POST https://api.vc.staging.opencampus.xyz/issuer/vc{
"credentialPayload": { ... },
"holderOcId": "bob.edu"
}{"validFrom": "2023-12-10T16:00:00.000Z",
"awardedDate": "2023-12-10T16:00:00.000Z",
"description": "An achievement for achieving outstanding results in mathematics course",
"credentialSubject": {
"name": "John Doe",
"type": "Person",
"email": "[email protected]",
"image": "https://img.freepik.com/premium-vector/gold-medal-with-gold-ribbon-that-says-gold_1134661-43944.jpg",
"profileUrl": "https://mycourse.xyz/profile/johndoe",
"achievement": {
"name": "Gold Medal Achievements",
"identifier": "tt:1111222333",
"description": "Reached 200 points in the intermediate mathematics",
"achievementType": "Achievement"
}
}
}POST https://api.vc.staging.opencampus.xyz/issuer/vc{
"credentialPayload": { ... },
"collectionSymbol": "ocbadge",
"holderOcId": "bob.edu"
}{
"credentialPayload": { ... },
"collectionSymbol": "ocbadge",
"holderAddress": "0xabcD12345..."{
"validFrom": "2023-12-10T16:00:00.000Z",
"awardedDate": "2023-12-10T16:00:00.000Z",
"description": "Season 3 Badge from XXXSwap",
"credentialSubject": {
"type": "Person",
"image": "https://img.freepik.com/premium-vector/gold-medal-with-gold-ribbon-that-says-gold_1134661-43944.jpg",
"profileUrl": "https://mycourse.xyz/profile/johndoe",
"achievement": {
"name": "LiquidityKing",
"identifier": "tt:1111222333",
"description": "transacting more than $100 in value on Sailfish",
"achievementType": "Badge"
},
}