<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jennifer K. Tran</title>
    <description>The latest articles on DEV Community by Jennifer K. Tran (@jkim_tran).</description>
    <link>https://dev.to/jkim_tran</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F688395%2F985ce843-514c-4926-8e10-66e80697fa57.png</url>
      <title>DEV Community: Jennifer K. Tran</title>
      <link>https://dev.to/jkim_tran</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jkim_tran"/>
    <language>en</language>
    <item>
      <title>How to Token Gate with POAP</title>
      <dc:creator>Jennifer K. Tran</dc:creator>
      <pubDate>Fri, 17 Dec 2021 00:51:17 +0000</pubDate>
      <link>https://dev.to/jkim_tran/how-to-token-gate-with-poap-1l0i</link>
      <guid>https://dev.to/jkim_tran/how-to-token-gate-with-poap-1l0i</guid>
      <description>&lt;p&gt;&lt;em&gt;This article outlines how to utilize Proof of Attendance Protocol’s (POAP) APIs to create a natively token gated application. Note that MintGate has a direct integration with POAP via the same APIs for our no-code token gating solution.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Proof of Attendance or POAP?
&lt;/h3&gt;

&lt;p&gt;Proof of Attendance Protocol (POAP) provides event nomads with a way to verify their attendance through collecting digital badges, all of which live on-chain.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is token gating?
&lt;/h3&gt;

&lt;p&gt;Token gating is when ownership of an NFT or social token is required to access content. Think of it as a creator or community creates a blockchain token and then sets up a paywall that only&lt;br&gt;
accepts that token to access exclusive content.&lt;/p&gt;

&lt;p&gt;Other terms to describe token gating include NFT access and NFT tickets.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why token gating with POAP? (Use Cases)
&lt;/h3&gt;

&lt;p&gt;Token gating with POAP means that an event host only allows event attendees who own a POAP badge to access certain content post-event. Gating content with a POAP badge enables event hosts to create unique experiences and build longer term relationships with event attendees.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Several use cases include&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only virtual call attendees can access the recorded call&lt;/li&gt;
&lt;li&gt;Attendees of an IRL event can access a site to claim swag&lt;/li&gt;
&lt;li&gt;Only attendees of a past event can RSVP to attend another event&lt;/li&gt;
&lt;li&gt;And More!&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to Utilize POAP’s APIs?
&lt;/h3&gt;

&lt;p&gt;Note that MintGate has a direct integration with POAP via the same APIs for our no-code token gating solution. Try it out at &lt;a href="https://app.mintgate.io/create_link" rel="noopener noreferrer"&gt;app.mintgate.io/create_link&lt;/a&gt; -&amp;gt; Input your URL and description -&amp;gt; Choose POAP as the blockchain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Creating a Token Gating App Works&lt;/strong&gt;&lt;br&gt;
In order to develop a token gated content platform, you ask a user for a wallet address, store the wallet address, and then pass it into an API that can check the user’s balance of the NFT or&lt;br&gt;
token.&lt;/p&gt;

&lt;p&gt;With Ethereum and EVM-based chains, you can utilize a wallet connection modal such as BlockNative Onboard or Web3Modal, store the wallet address that is returned, and use a blockchain connection API such as Infura to check token balances.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Working with POAP&lt;/strong&gt;&lt;br&gt;
Though POAPs are minted on xDAI, an EVM-based chain, POAP holders of the same event can have various different NFTs. As a result, it is difficult to check all of the NFTs using an API that can connect to the blockchain.&lt;/p&gt;

&lt;p&gt;Instead, you can should check if a user owns a POAP by the POAP Event ID. The POAP Event ID is a set of numbers that identifies the event. &lt;/p&gt;

&lt;p&gt;You can find a POAP Event ID by going to &lt;a href="https://poap.gallery/" rel="noopener noreferrer"&gt;poap.gallery&lt;/a&gt;, searching for the POAP, and the event ID is the numbers with the # in front.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4dwzwm0seoosmghgfa94.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4dwzwm0seoosmghgfa94.PNG" alt="Example of POAP Search Result with POAP Event ID highlighted"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can utilize &lt;a href="https://api.poap.xyz/documentation/static/#/Tokens/get_actions_scan__address___eventId_" rel="noopener noreferrer"&gt;POAP’s {address}/{eventID} endpoint&lt;/a&gt; to check if a wallet address owns a wallet by a POAP Event ID.&lt;/p&gt;

&lt;p&gt;Here is an example code to check if a wallet address owns a POAP by Event ID:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             async checkBalance(wallet:string, eventID:string, req, res):Promise&amp;lt;boolean&amp;gt; {
    const url = 
       `http://api.poap.xyz/actions/scan/${wallet}/${eventID}`

            const result = await fetch(url).then(x=&amp;gt;x.json());

            if(!result) {
                 console.error('No POAP Information available');
                 return false;
             }

            const message = result.message;
            const eventValid = result.event;

    if (result.status == '404' || message == 'Address does not have token for this event') {
        return false;`
    } else if (eventValid) {
        return true;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The API enables you to easily check balances of a POAP without utilizing more complicated APIs that connect to the blockchain. &lt;/p&gt;

&lt;p&gt;Token gating post-event assets by POAP enables event hosts to create unique experiences for event attendees. Hope that you consider token gating via POAP soon!&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Add Custom Rally Login into an Ethereum Wallet Modal</title>
      <dc:creator>Jennifer K. Tran</dc:creator>
      <pubDate>Wed, 06 Oct 2021 02:46:09 +0000</pubDate>
      <link>https://dev.to/jkim_tran/how-to-add-custom-rally-login-into-an-ethereum-wallet-modal-keh</link>
      <guid>https://dev.to/jkim_tran/how-to-add-custom-rally-login-into-an-ethereum-wallet-modal-keh</guid>
      <description>&lt;p&gt;This article outlines how to add &lt;a href="https://rally.io/" rel="noopener noreferrer"&gt;Rally.io&lt;/a&gt; login to Onboard.js, a modal integration that allows users to login into decentralized apps using various Ethereum wallets.&lt;/p&gt;

&lt;p&gt;Since Rally is not an Ethereum Virtual Machine (EVM) compatible blockchain, developers must separate the Rally and Ethereum wallet authentications on their dapps. &lt;/p&gt;

&lt;p&gt;However, &lt;a href="https://docs.blocknative.com/onboard" rel="noopener noreferrer"&gt;Onboard.js&lt;/a&gt; simplifies the UI and allows dapps to easily add new Ethereum wallets and custom logins as user login options. &lt;/p&gt;

&lt;p&gt;To learn more about the key differences between Rally and Ethereum, check out this article &lt;a href="https://dev.to/jkim_tran/how-is-rally-different-from-ethereum-mainnet-248a"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Set up Onboard.js (if you have not already)
&lt;/h3&gt;

&lt;p&gt;You will need to add the Onboard.js as a package and initialize the library in your Javascript project.&lt;/p&gt;

&lt;p&gt;You can follow the documentation to add Onboard.js to your project &lt;a href="https://docs.blocknative.com/onboard" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;As noted in the docs, to initialize the built-in wallet modules, you must pass an array of wallet initialization objects to the walletSelect.wallets parameter of the Onboard initialization object.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Create a Rally.io login module
&lt;/h3&gt;

&lt;p&gt;Create a new Javascript module. In the module, you will need to add the following:&lt;/p&gt;

&lt;p&gt;An constant variable that stores the Rally starlight logo SVG:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const rallySVG = `&amp;lt;svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve"&amp;gt;
&amp;lt;style type="text/css"&amp;gt;
.st0{fill:#FFFFFF;}
.st1{clip-path:url(#SVGID_2_);}
&amp;lt;/style&amp;gt;
&amp;lt;g&amp;gt;
&amp;lt;path class="st0" d="M57.52,63.66"/&amp;gt;
&amp;lt;path class="st0" d="M72.92,35.95c0.33,0,0.6,0.27,0.6,0.6c0,14.02,8.64,24.87,25.39,25.22c0.33,0,0.6,0.27,0.6,0.6
 s-0.27,0.6-0.6,0.6C82.15,63.3,73.51,74.15,73.51,88.17c0,0.33-0.27,0.6-0.6,0.6c-0.33,0-0.6-0.27-0.6-0.6
 c0-14.02-8.64-24.87-25.39-25.22c-0.33,0-0.6-0.27-0.6-0.6s0.27-0.6,0.6-0.6c16.75-0.34,25.39-11.19,25.39-25.22
 C72.32,36.22,72.59,35.95,72.92,35.95z"/&amp;gt;
&amp;lt;g&amp;gt;
 &amp;lt;g&amp;gt;
   &amp;lt;defs&amp;gt;
     &amp;lt;path id="SVGID_1_" d="M46.93,62.96c16.75,0.34,25.39,11.19,25.39,25.22c0,0.33-0.27,0.6-0.6,0.6H1.1c-0.33,0-0.6-0.27-0.6-0.6
       V11.83c0-0.33,0.27-0.6,0.6-0.6h45.78c13.96,0.29,25.44,11.29,25.44,25.32s-8.64,24.87-25.39,25.22c-0.33,0-0.6,0.27-0.6,0.6
       S46.6,62.96,46.93,62.96z"/&amp;gt;
   &amp;lt;/defs&amp;gt;
   &amp;lt;clipPath id="SVGID_2_"&amp;gt;
     &amp;lt;use xlink:href="#SVGID_1_"  style="overflow:visible;"/&amp;gt;
   &amp;lt;/clipPath&amp;gt;
   &amp;lt;g class="st1"&amp;gt;
     &amp;lt;g&amp;gt;
       &amp;lt;defs&amp;gt;
         &amp;lt;rect id="SVGID_3_" x="-4.5" y="6.23" width="81.82" height="87.54"/&amp;gt;
       &amp;lt;/defs&amp;gt;
       &amp;lt;clipPath id="SVGID_4_"&amp;gt;
         &amp;lt;use xlink:href="#SVGID_3_"  style="overflow:visible;"/&amp;gt;
       &amp;lt;/clipPath&amp;gt;
       &amp;lt;g style="clip-path:url(#SVGID_4_);"&amp;gt;

           &amp;lt;image style="overflow:visible;" width="172" height="184" xlink:href="data:image/jpeg;base64,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
Ox+w5PN+V1d2tz87sn//2Q==" transform="matrix(0.48 0 0 0.48 -4.8 5.76)"&amp;gt;
         &amp;lt;/image&amp;gt;
       &amp;lt;/g&amp;gt;
     &amp;lt;/g&amp;gt;
   &amp;lt;/g&amp;gt;
 &amp;lt;/g&amp;gt;
&amp;lt;/g&amp;gt;
&amp;lt;/g&amp;gt;
&amp;lt;/svg&amp;gt;`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create an export module that will direct the user to the callback that you stored the Rally.io login logic to. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: You will still need to add backend logic that will handle the Rally.io login. To learn more about how to set up Rally.io login, review the docs &lt;a href="https://api-docs.rally.io/" rel="noopener noreferrer"&gt;here&lt;/a&gt; or subscribe to my account for upcoming articles!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const customRallyLogin = {
  name: 'Rally', //display name of the wallet
  preferred: true, //lists Rally login as a top login option
  svg: rallySVG,
  wallet: async helpers =&amp;gt; {
    window.location.href = 'yourcallback';
    await new Promise(resolve =&amp;gt; setTimeout(resolve, 10000));
    return null;
  },
  desktop: true,
  mobile: true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Import the Rally Login module to Onboard.js
&lt;/h3&gt;

&lt;p&gt;Import the Rally Login module into the Onboard initialization.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { customRallyLogin } from "../../utils/logins/Rally";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the module name under the walletSelect.wallets parameter of the Onboard initialization object, alongside the other wallet integrations.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    { walletName: "metamask", preferred: true },
    { walletName: "torus", preferred: true },
    { walletName: "coinbase", preferred: true }, 
    customRallyLogin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: End Result
&lt;/h3&gt;

&lt;p&gt;Once you add the wallet model to an onClick method to a Login button, the Onboard.js module will popup and Rally is listed as a login option.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxa7dj9z4syut8kg7yys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxa7dj9z4syut8kg7yys.png" alt="Rally Login on Onboard.js module"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How is Rally different from Ethereum Mainnet?</title>
      <dc:creator>Jennifer K. Tran</dc:creator>
      <pubDate>Fri, 01 Oct 2021 01:51:20 +0000</pubDate>
      <link>https://dev.to/jkim_tran/how-is-rally-different-from-ethereum-mainnet-248a</link>
      <guid>https://dev.to/jkim_tran/how-is-rally-different-from-ethereum-mainnet-248a</guid>
      <description>&lt;p&gt;This article outlines the key differences between the Rally network and Ethereum mainnet, two blockchains widely used to create "social tokens" or cryptocurrencies that represent artists, creators, and communities. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is Rally and Ethereum?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Ethereum
&lt;/h3&gt;

&lt;p&gt;Ethereum is the most popular built-upon blockchain. Developers have built thousands of applications, tools, protocols, and cryptocurrencies on the Ethereum blockchain, more than any blockchain by far.&lt;/p&gt;

&lt;p&gt;Hundreds of creators and communities have created their own social tokens on Ethereum, most notably with &lt;a href="https://tryroll.com/"&gt;Roll&lt;/a&gt; and &lt;a href="https://www.coinvise.co/"&gt;Coinvise&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Ethereum Virtual Machine (EVM) compatible sidechains
&lt;/h3&gt;

&lt;p&gt;Most recently, Ethereum Virtual Machine (EVM) compatible sidechains or secondary blockchains based on the Ethereum network have formed. The most popular include &lt;a href="https://www.xdaichain.com/"&gt;xDai&lt;/a&gt; and &lt;a href="https://www.polygon.com/"&gt;Polygon&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;These sidechains allow users to create tokens that are compatible with the Ethereum blockchain. Since EVM compatible chains are based off of Ethereum, many tools, applications, and protocols built on Ethereum can utilize the same templates to integrate with EVM compatible chains.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rally
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://rally.io/"&gt;Rally network&lt;/a&gt; is a non-EVM compatible blockchain that is widely-known for social tokens. Currently, dozens of major creators, from Grammy Award winning producer !llmind and popular Twitch streamer Alliestrasza, have created their social token via Rally. &lt;/p&gt;

&lt;h2&gt;
  
  
  What are the key differences between Ethereum, EVM compatible chains, and Rally?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. How to Identify the Blockchains
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Ethereum and EVM compatible chains
&lt;/h4&gt;

&lt;p&gt;The Ethereum blockchain and each EVM compatible chain is assigned a positive number unique network, chain ID, and an RPC method. &lt;/p&gt;

&lt;h4&gt;
  
  
  Rally
&lt;/h4&gt;

&lt;p&gt;The Rally network is built on top of a larger blockchain ecosystem named Forte. The Rally network is identified as Rally and does not have a numeric network or chain ID. &lt;/p&gt;

&lt;h3&gt;
  
  
  2. How to Identify Tokens
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Ethereum and EVM compatible chains
&lt;/h4&gt;

&lt;p&gt;A non-fungible or cryptocurrency-like token on the Ethereum blockchain and EVM compatible chains have the following attributes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Contract address (numeric identifier of token)&lt;/li&gt;
&lt;li&gt;Name of the token (symbol/name of the token)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since different tokens can have the same name but not the same contract address, developers must rely on the contract address to identify tokens. &lt;/p&gt;

&lt;h4&gt;
  
  
  Rally
&lt;/h4&gt;

&lt;p&gt;A social token on Rally identified by its symbol, starting with $. &lt;/p&gt;

&lt;p&gt;Unlike on Ethereum or EVM chains, the social token symbol is unique and is the sole identifier. &lt;/p&gt;

&lt;h3&gt;
  
  
  3. How A User Interacts with the Blockchain
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Ethereum and EVM compatible chains
&lt;/h4&gt;

&lt;p&gt;To interact with the Ethereum and EVM compatible blockchains, users create a digital wallet that is assigned a 42-character identifier called a wallet address.&lt;/p&gt;

&lt;p&gt;A user can utilize the same wallet with the same wallet address across any Ethereum or EVM compatible chain.&lt;/p&gt;

&lt;h4&gt;
  
  
  Rally
&lt;/h4&gt;

&lt;p&gt;To interact with the Rally blockchain, users create an email login with a username and password on Rally.io. &lt;/p&gt;

&lt;p&gt;A username is assigned an number-alpha identifier named a Rally ID on the backend. The Rally ID is often needed to develop login capabilities on the apps. The user often only needs their username and does not need the Rally ID to interact with the Rally chain.&lt;/p&gt;

&lt;p&gt;Unlike on Ethereum and side-chains, the Rally login system is more friendly to users. Depending on how you set up the authentication of your app, the Rally login is less cumbersome. Since there is only one login method for users on Rally, developers do not need to keep track of hundreds of wallets that can connect to the chain.  &lt;/p&gt;

&lt;h3&gt;
  
  
  4. How A Developer Integrates with Wallet Login
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Ethereum and EVM compatible chains
&lt;/h4&gt;

&lt;p&gt;To integrate digital wallet login on an app, a developer must receive an object with the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wallet provider (the name of the wallet i.e. Metamask)&lt;/li&gt;
&lt;li&gt;Wallet address (the specific identifier of wallet account)&lt;/li&gt;
&lt;li&gt;User signature (the hash confirmation that returns when the user "signs" their wallet prompt or confirms that they own the wallet)&lt;/li&gt;
&lt;li&gt;Network (identifier for blockchain)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wallet modal SDKs such as &lt;a href="https://github.com/Web3Modal/web3modal"&gt;Web3Modal&lt;/a&gt; and &lt;a href="https://docs.blocknative.com/onboard"&gt;BlockNative Onboard&lt;/a&gt; enable simpler integrations with a wide variety of Ethereum and EVM compatible wallets. &lt;/p&gt;

&lt;h4&gt;
  
  
  Rally
&lt;/h4&gt;

&lt;p&gt;To integrate Rally login, a developer must register their app callback and account credentials with Rally and integrate their specific Rally Authentication system. &lt;/p&gt;

&lt;p&gt;Current Steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Once the app and account credentials are registered, the developer will pass in their account credentials to the
&lt;code&gt;v1/oauth/register&lt;/code&gt; API to obtain a bearer token.&lt;/li&gt;
&lt;li&gt;They will then pass the bearer token and callback of their application registered to Rally to &lt;code&gt;v1/oauth/authorize&lt;/code&gt;. This API will return a Rally.io login link that your app must direct the user to sign in.&lt;/li&gt;
&lt;li&gt;Once the Rally user signs in, they will redirect back to the callback that you registered with Rally in in Step 2 with an additional param named &lt;code&gt;code&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You will pass in the value in the code param into &lt;code&gt;v1/oauth/userinfo&lt;/code&gt; to receive the Rally username.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This Rally username is the equivalent of a user "wallet address" in Ethereum. &lt;/p&gt;

&lt;h3&gt;
  
  
  5. How Access Data on Chain
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Ethereum and EVM compatible chains
&lt;/h4&gt;

&lt;p&gt;Since the Ethereum and EVM chains are completely open, there are numerous ways to access and index data on their chains. &lt;/p&gt;

&lt;p&gt;Several marketplaces create their own APIs specific to tokens minted on their platforms. Indexers such as &lt;a href="https://thegraph.com/en/"&gt;The Graph&lt;/a&gt; allow you to create your own APIs to index specific contract addresses or created tokens. &lt;/p&gt;

&lt;h4&gt;
  
  
  Rally
&lt;/h4&gt;

&lt;p&gt;Rally is the sole provider of APIs on its blockchain. You can find the API docs &lt;a href="https://api-docs.rally.io/"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Though there are less options to get data from the chain, a single source provider can streamline the returned data format. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Conclusion
&lt;/h2&gt;

&lt;p&gt;The Ethereum and Rally blockchains are the two most widely known chains to minting social tokens, a new use case for blockchain tokens that enables creators and communities to become independent. Ethereum and its EVM side chains have strong support and compatibility that allows for rapid mass integration. Though Rally follows a different process to accessing its chain, Rally enables a streamlined approach that is more user friendly to users.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>rally</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to access data from a subgraph on The Graph</title>
      <dc:creator>Jennifer K. Tran</dc:creator>
      <pubDate>Tue, 17 Aug 2021 20:02:42 +0000</pubDate>
      <link>https://dev.to/jkim_tran/how-to-access-data-from-a-subgraph-on-the-graph-dk3</link>
      <guid>https://dev.to/jkim_tran/how-to-access-data-from-a-subgraph-on-the-graph-dk3</guid>
      <description>&lt;p&gt;This article outlines how to access data from a subgraph or API created on The Graph, as well as how to combine subgraph results using a React hook. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is The Graph?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://thegraph.com/" rel="noopener noreferrer"&gt;The Graph&lt;/a&gt; is an indexing protocol for querying networks. One of its core features is that anyone can use The Graph to build APIs of smart contract data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our Use Case
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.mintgate.io" rel="noopener noreferrer"&gt;MintGate&lt;/a&gt; is a platform that allows creators and communities to set up gated videos and web content using NFTs or social tokens. &lt;a href="https://unlock-protocol.com/" rel="noopener noreferrer"&gt;Unlock Protocol&lt;/a&gt; is an open source, blockchain-based protocol that allows anyone to create membership, time-based NFTs. &lt;/p&gt;

&lt;p&gt;A MintGate and Unlock Protocol integration would allow creators and communities to require an end fan to purchase an NFT to access content for a certain period of time. In our UI, we needed to detect if a user set up gated content using an NFT smart contract created on Unlock Protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Using Unlock Protocol's subgraphs on The Graph
&lt;/h3&gt;

&lt;p&gt;We utilized Unlock Protocol's subgraphs on The Graph to get the contract addresses of all "locks" or NFT collections created using the protocol. You can view all of Unlock Protocol's subgraph information in their &lt;a href="https://docs.unlock-protocol.com/developers/subgraph" rel="noopener noreferrer"&gt;docs&lt;/a&gt;. &lt;/p&gt;

&lt;h4&gt;
  
  
  Step One
&lt;/h4&gt;

&lt;p&gt;We created a new Javascript file and wrapped a React &lt;code&gt;UseAsync&lt;/code&gt; hook in a const.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useAsync } from 'react-use';

const useUnlock = () =&amp;gt; {
    const unlock = useAsync(async () =&amp;gt; {
    }
}

export { useUnlock };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step Two
&lt;/h4&gt;

&lt;p&gt;We analyzed the subgraphs and outlined how to structure the fetch call.&lt;/p&gt;

&lt;p&gt;Here's link to the Unlock Protocol mainnet subgraph on The Graph: &lt;a href="https://thegraph.com/legacy-explorer/subgraph/unlock-protocol/unlock" rel="noopener noreferrer"&gt;https://thegraph.com/legacy-explorer/subgraph/unlock-protocol/unlock&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Notes on subgraphs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The fetch API URL is the API link under "Queries (HTTP)".&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frtn2nfayu3rgrv7hc6ds.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frtn2nfayu3rgrv7hc6ds.jpg" alt="Pointing to API URL on The Graph"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Subgraphs are POST APIs.&lt;/li&gt;
&lt;li&gt;In The Graph Playground, under Example Query box, there are examples of a request body.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgg7eci64vf8yhoajiwuq.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgg7eci64vf8yhoajiwuq.PNG" alt="Example of a Request Body"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In The Graph Playground, under the Schema, it lists the entries that you can index in the API.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zotyguevygqdpsxz2uw.PNG" alt="Schema"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Step Three
&lt;/h4&gt;

&lt;p&gt;Now that we analyzed the subgraph, we constructed our fetch call.&lt;/p&gt;

&lt;p&gt;For us, since we wanted to get the lock or NFT collection name, we used this request body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query {
        locks {
          address
          name
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our params are as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const result = await fetch(`https://api.thegraph.com/subgraphs/name/unlock-protocol/unlock`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        query: `
      query {
        locks {
          address
          name
        }
    }`
      }),
    }),
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step Four
&lt;/h4&gt;

&lt;p&gt;After we set up the params, we set up returning the result of the API.&lt;/p&gt;

&lt;p&gt;We added this to the end of const containing the params:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;then((res) =&amp;gt; res.json());
    return result; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Wrapping Up
&lt;/h4&gt;

&lt;p&gt;You returned the const the contained the fetch call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;}, []);
  return [unlock];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And exported the const the wraps around the entire React hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export { useUnlock };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our end result looked something similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useAsync } from 'react-use';

const useUnlockMainnet = () =&amp;gt; {
  const unlockMainnet = useAsync(async () =&amp;gt; {
    const result = await fetch(`https://api.thegraph.com/subgraphs/name/unlock-protocol/unlock`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        query: `
      query {
        locks {
          address
        }
    }
  }`
      }),
    }).then((res) =&amp;gt; res.json());
    return result;
  }, []);
  return [unlockMainnet];
}

export { useUnlockMainnet };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Bonus Points: How to call multiple subgraph results
&lt;/h3&gt;

&lt;p&gt;In addition, we needed a way to check if a user gated content using an Unlock Protocol lock or smart contract on other chains besides Ethereum mainnet.&lt;/p&gt;

&lt;p&gt;We needed to utilize the subgraphs on &lt;a href="https://thegraph.com/legacy-explorer/subgraph/unlock-protocol/xdai" rel="noopener noreferrer"&gt;xDai&lt;/a&gt; and &lt;a href="https://thegraph.com/legacy-explorer/subgraph/unlock-protocol/polygon" rel="noopener noreferrer"&gt;Polygon&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Using Promise.All, you fetched all of the responses and had them return in an array. Here was our end result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useAsync } from 'react-use';

const useUnlock = () =&amp;gt; {
  const unlock = useAsync(async () =&amp;gt; {
    const result = await Promise.all([await fetch(`https://api.thegraph.com/subgraphs/name/unlock-protocol/unlock`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        query: `
      query {
        locks {
          address
          name
        }
    }`
      }),
    }),
    await fetch(`https://api.thegraph.com/subgraphs/name/unlock-protocol/xdai
      `, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        query: `
        query {
          locks {
            address
            name
          }
      }`
      }),
    }),
    await fetch(`https://api.thegraph.com/subgraphs/name/unlock-protocol/polygon
      `, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        query: `
        query {
          locks {
            address
            name
          }
      }`
      }),
    })]);
    const data = await Promise.all(result.map(res =&amp;gt; res.json()))
    return data;
  }, []);
  return [unlock];
}

export { useUnlock };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can try to create an Unlock lock and set up token gated content on MintGate today! &lt;/p&gt;

</description>
      <category>react</category>
      <category>graphql</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
