# Single Chain integration

There are two aspects to consider when integrating the VIP3 SBT:

1. Do I need the VIP3 SBT data on-chain or off-chain?
2. Do I just need to check if the address holds one or know the detailed traits of the VIP3 SBT

\
The on-chain method is typically employed when a decentralized application (dApp) directly engages with a contract, with all the operational logic contained within the dApp's contract. The dApp contract can directly access the necessary data from the VIP3 SBT contract. However, using the on-chain approach can lead to an increase in the gas required for contract execution.

\
On the other hand, the off-chain method is commonly utilized when a dApp can interact both with a contract and a backend service. This backend service can obtain information from the VIP3 SBT by using services provided by an Ethereum API provider. Consequently, the Dapp can acquire all the necessary data from this backend service. Additionally, the contract can also utilize the information obtained by the backend service. Within the contract's logic, it can verify the signature of the information which is about VIP3 SBT provided by the backend service to ensure the accuracy of the data.

\
Check the table below to understand what integration suits your needs best:

<table><thead><tr><th width="152.33333333333331"></th><th>Use data on-chain</th><th>Use data off-chain</th></tr></thead><tbody><tr><td>Verify Holder<br></td><td>VIP3 SBT smart contract<br></td><td><p>VIP3 SBT smart contract</p><p>Ethereum API Provider(ex: Infura, QuickNode)</p></td></tr><tr><td>Detail traits<br></td><td>VIP3 SBT Level traits can be get from the smart contract. Other details traits are not available on-chain<br></td><td><p>Ethereum API Provider(ex: Infura, QuickNode)</p><p>VIP3 SBT metadata API (based on s3)<br></p></td></tr></tbody></table>

#### Off-chain Integration

The easiest way of integrating the SBT traits is by using API provided by popular node providers, like Infura, and QuickNode. It returns a user's SBT URI which can directly access an easily digestible JSON format for the SBT detail.

**Verifying a VIP3 SBT Holder**

Take the alchemy Ethereum chain for example (python version):

```
import requests

def isholderofVIP3(alchemy_api_key, wallet_address): 
url = "https://eth-mainnet.g.alchemy.com/nft/v2/{0}/isHolderOfCollection?wallet={0}&contractAddress=0xabe292b291a18699b09608de86888d77ad6baf23".format( wallet_address) 
headers = {"accept": "application/json"} 
response = requests.get(url, headers=headers) 
print(response.text)
```



Response:

```
{"isHolderOfCollection": true}
```



Verify on other chains, you can replace the below urls and contract address

<table><thead><tr><th width="183">Chain</th><th width="88">ChainId</th><th>Contract Address</th><th>URL Prefix</th></tr></thead><tbody><tr><td>eth</td><td>1</td><td>0xabe292b291a18699b09608de86888d77ad6baf23</td><td>https://eth-mainnet.g.alchemy.com/nft/v2/{apiKey}</td></tr><tr><td>eth_goerli</td><td>5</td><td>0x570b5e80152D54a476b98635de26B523dDFbDBDC</td><td>https://eth-goerli.g.alchemy.com/v2/{apiKey}</td></tr><tr><td>polygon</td><td>137</td><td>0xabe292b291a18699b09608de86888d77ad6baf23</td><td>https://polygon-mainnet.g.alchemy.com/v2/{apiKey}</td></tr><tr><td>polygon-mumbai</td><td>80001</td><td>0x570b5e80152D54a476b98635de26B523dDFbDBDC</td><td>https://polygon-mumbai.g.alchemy.com/v2/{apiKey}</td></tr><tr><td>zksync_era</td><td>324</td><td>0xf5bf718bEafc62503aa5b30E982ee2e050632Df1</td><td>Up Coming</td></tr><tr><td>zksync_era_testnet</td><td>280</td><td>0x32Ab0E82D639532100c50889D4636499A2f53308</td><td>Up Coming</td></tr></tbody></table>

**Get a VIP3 SBT Trait**

The SBT metadata for Ethereum can be fetched at: https://vip3eth.s3.amazonaws.com/metadata/\<SBT\_ID>The API returns all available data about a user's SBT like: **description, image, name**, or **attributes**.

Since the trait `value` is a string it is required to interpret the value according to the **SBT Traits Demo**

Get traits from other chains, you can use the below urls

| Chain                | ChainId | URL Prefix                                                |
| -------------------- | ------- | --------------------------------------------------------- |
| eth                  | 1       | https://vip3eth.s3.amazonaws.com/metadata/\<SBT\_ID>      |
| eth\_goerli          | 5       | https://vip3goerli.s3.amazonaws.com/metadata/\<SBT\_ID>   |
| polygon              | 137     | https://vip3polygon.s3.amazonaws.com/metadata/\<SBT\_ID>  |
| polygon-mumbai       | 80001   | https://vip3polytest.s3.amazonaws.com/metadata/\<SBT\_ID> |
| zksync\_era          | 324     | https://vip3zk.s3.amazonaws.com/metadata/\<SBT\_ID>       |
| zksync\_era\_testnet | 280     | https://vip3zktest.s3.amazonaws.com/metadata/\<SBT\_ID>   |



#### On-chain Integration

The Ethereum VIP3 SBT contract can be found at: [**VIP3SBT**](https://etherscan.io/token/0xabe292b291a18699b09608de86888d77ad6baf23) **, contract source can be found at :** [**source**](https://etherscan.io/address/0x8c213e9ad5846237095f2a5a38c247e97c47081e#code)You can get the contract and source file for other chains in the below urls:

| Chain                | Contract                                                                                      |
| -------------------- | --------------------------------------------------------------------------------------------- |
| eth                  | https://etherscan.io/token/0xabe292b291a18699b09608de86888d77ad6baf23                         |
| eth\_goerli          | https://goerli.etherscan.io/address/0x570b5e80152D54a476b98635de26B523dDFbDBDC                |
| polygon              | https://polygonscan.com/address/0xabe292b291a18699b09608de86888d77ad6baf23                    |
| polygon-mumbai       | https://mumbai.polygonscan.com/address/0x570b5e80152D54a476b98635de26B523dDFbDBDC             |
| zksync\_era          | https://explorer.zksync.io/address/0xf5bf718bEafc62503aa5b30E982ee2e050632Df1#contract        |
| zksync\_era\_testnet | https://goerli.explorer.zksync.io/address/0x32Ab0E82D639532100c50889D4636499A2f53308#contract |

The VIP3 SBT Smart contract exposes a simple API to integrate with the SBT on-chain.



{% hint style="info" %}
INFO

Since only owners are stored on-chain the contract can only return a result for SBT Id
{% endhint %}

```
interface IVIP3SBT {
/**
* @notice Count all SBTs assigned to an owner
* @dev SBTs assigned to the zero address is considered invalid, and this
* function throws for queries about the zero address.
* @param owner An address for whom to query the balance
* @return The number of SBTs owned by owner, possibly zero
*/function balanceOf(address owner) external view returns (uint256);

/**
* @param from The address of the SBT owner* @return The tokenId of the owner's SBT, and throw an error if there is no SBT belonging to the given address*/function tokenIdOf(address from) external view returns (uint256);

/**
* @notice Find the address bound to a SBT
* @dev SBTs assigned to zero address are considered invalid, and queries
* about them do throw.
* @param tokenId The identifier for an SBT
* @return The address of the owner bound to the SBT
*/function ownerOf(uint256 tokenId) external view returns (address);

/**
* @dev Returns the amount of tokens in existence.
*/function totalSupply() external view returns (uint256);

/**
* @dev Returns the Uniform Resource Identifier (URI) for tokenId token.
*/function tokenURI(uint256 tokenId) external view returns (string memory);

/**
* @dev Returns the Level for tokenId token.*/function getLevel(uint256 tokenId) external view returns (uint256);
}

```

**Verifying a VIP3 SBT Holder**

To check if a user has a VIP3 SBT the _**balanceOf**_ method should be used.

**Get a VIP3 SBT URI**

To get the uri of a VIP3 SBT the _**tokenURI**_ method should be used.

**Get a VIP3 SBT Level**

To get the uri of a VIP3 SBT the _**getLevel**_ method should be used.
