REST API for retrieving data from Holonym smart contracts.
Built so that projects can integrate Holo with two lines of code.
- Optimism
- Optimism Goerli
We plan to support more chains in the future. If you would like to use Holonym on a chain other than the ones currently supported, please reach out to us. You can find ways to contact us on our website.
- GET
/sbts/<credential-type>/
- GET
/sybil-resistance/gov-id/<network>
- GET
/sybil-resistance/epassport/<network>
- GET
/sybil-resistance/phone/<network>
- GET
/residence/country/us/<network>
- GET
/snapshot-strategies/residence/country/us
- GET
/snapshot-strategies/sybil-resistance/gov-id
- GET
/snapshot-strategies/sybil-resistance/phone
- GET
/attestation/attestor
- GET
/attestation/sbts/gov-id
(Differs slightly from sybil-resistance endpoints.)
-
Parameters
name description type in required credential-type
'kyc', 'epassport', or 'phone' string path true address
User's blockchain address string query true -
Example
const resp = await fetch('https://api.holonym.io/sbts/kyc?address=0x0000000000000000000000000000000000000000'); const { hasValidSbt, message } = await resp.json();
-
Responses
-
200
{ "hasValidSbt": true, }
-
200
Result if user's SBT has expired
{ "hasValidSbt": false, "message": "SBT is expired or does not exist" }
-
Get whether the user has registered for the given action-id.
When a user "registers", they are establishing that the given blockchain address is a unique person for the action ID. See the section Sybil resistance for more information about how action IDs can be used.
If credential-type
is gov-id
, this endpoint uses the government ID Holonym smart contract to check whether the user is unique. If credential-type
is phone
, this endpoint uses the phone number Holonym smart contract to check whether the user is unique.
See the following documentation How to get user's proofs for how to use action IDs.
-
Parameters
name description type in required credential-type
'gov-id', 'epassport', or 'phone' string path true network
'optimism' or 'base-sepolia' string path true user
User's blockchain address string query true action-id
Action ID string query true -
Example
const resp = await fetch('https://api.holonym.io/sybil-resistance/gov-id/optimism?action-id=123456789&user=0x0000000000000000000000000000000000000000'); const { result: isUnique } = await resp.json();
-
Responses
-
200
{ "result": true, }
-
200
Result if user has not submitted a valid proof.
{ "result": false, }
-
Get whether the user resides in the US.
For the /residence/country/<country-code>
endpoints, <country-code>
will be a 2-letter country code following the ISO 3166 standard. Holonym currently only supports queries for US residency.
-
Parameters
name description type in required network
'optimism' or 'optimism-goerli' string path true user
User's blockchain address string query true -
Example
const resp = await fetch('https://api.holonym.io/residence/country/us/optimism?user=0x0000000000000000000000000000000000000000'); const { result: isUSResident } = await resp.json();
-
Responses
-
200
Result if user resides in the US.
{ "result": true, }
-
200
Result if user has not submitted a valid proof that they reside in the US.
{ "result": false, }
-
GET /snapshot-strategies/residence/country/us?network=<network>&snapshot=<snapshot>&addresses=<addresses>
Returns a list of scores indicating, for each address, whether the address has submitted a valid and unique proof of US residency.
Every score is either 1 or 0.
score | description |
---|---|
1 | Address has proven US residency |
0 | Address has not proven US residency |
To use with the "api" Snapshot strategy, specify the strategy parameters using the following format.
{
"api": "https://api.holonym.io",
"symbol": "",
"decimals": 0,
"strategy": "snapshot-strategies/residence/country/us"
}
-
Parameters
name description type in required network
Chain ID string query true snapshot
Block height string query true addresses
List of blockchain address separated by commas string query true -
Example
const resp = await fetch('https://api.holonym.io/snapshot-strategies/residence/country/us?network=420&snapshot=9001&addresses=0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000001'); const data = await resp.json();
-
Responses
-
200
{ "score" : [ { "address" : "0x0000000000000000000000000000000000000000", "score" : 0 }, { "address" : "0x0000000000000000000000000000000000000001", "score" : 1 } ] }
-
GET /snapshot-strategies/sybil-resistance/gov-id?network=<network>&snapshot=<snapshot>&addresses=<addresses>&action-id=<action-id>
Returns a list of scores indicating, for each address, whether the address has submitted a valid proof of uniqueness (using government ID) for the given action-id.
Every score is either 1 or 0.
score | description |
---|---|
1 | Address has proven uniqueness for action-id |
0 | Address has not proven uniqueness for action-id |
To use with the "api" Snapshot strategy, specify the strategy parameters using the following format. We suggest that you use the default action-id 123456789
. If you are using a different action-id, replace 123456789
with your action-id.
{
"api": "https://api.holonym.io",
"symbol": "",
"decimals": 0,
"strategy": "snapshot-strategies/sybil-resistance/gov-id",
"additionalParameters": "action-id=123456789"
}
-
Parameters
name description type in required network
Chain ID string query true snapshot
Block height string query true addresses
List of blockchain address separated by commas string query true -
Example
const resp = await fetch('https://api.holonym.io/snapshot-strategies/sybil-resistance/gov-id?network=420&snapshot=9001&addresses=0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000001&action-id=123'); const data = await resp.json();
-
Responses
-
200
{ "score" : [ { "address" : "0x0000000000000000000000000000000000000000", "score" : 0 }, { "address" : "0x0000000000000000000000000000000000000001", "score" : 1 } ] }
-
GET /snapshot-strategies/sybil-resistance/phone?network=<network>&snapshot=<snapshot>&addresses=<addresses>&action-id=<action-id>
Returns a list of scores indicating, for each address, whether the address has submitted a valid proof of uniqueness (using phone number) for the given action-id.
Every score is either 1 or 0.
score | description |
---|---|
1 | Address has proven uniqueness for action-id |
0 | Address has not proven uniqueness for action-id |
To use with the "api" Snapshot strategy, specify the strategy parameters using the following format. We suggest that you use the default action-id 123456789
. If you are using a different action-id, replace 123456789
with your action-id.
{
"api": "https://api.holonym.io",
"symbol": "",
"decimals": 0,
"strategy": "snapshot-strategies/sybil-resistance/phone",
"additionalParameters": "action-id=123456789"
}
-
Parameters
name description type in required network
Chain ID string query true snapshot
Block height string query true addresses
List of blockchain address separated by commas string query true -
Example
const resp = await fetch('https://api.holonym.io/snapshot-strategies/sybil-resistance/phone?network=420&snapshot=9001&addresses=0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000001&action-id=123'); const data = await resp.json();
-
Responses
-
200
{ "score" : [ { "address" : "0x0000000000000000000000000000000000000000", "score" : 0 }, { "address" : "0x0000000000000000000000000000000000000001", "score" : 1 } ] }
-
-
Example
const resp = await fetch('https://api.holonym.io/attestation/attestor'); const { address } = await resp.json();
Returns isUnique
, a boolean indicating whether the user is unique for the given action ID using government ID, and (only if the user is unique) signature
, the attestor's personal_sign signature of the concatenation of action-id
and user-address
.
-
Example
const actionId = 123456789 const userAddress = '0xdbd6b2c02338919EdAa192F5b60F5e5840A50079' const resp = await fetch(`https://api.holonym.io/attestation/sbts/gov-id?action-id=${actionId}&address=${userAddress}`) const { isUnique, signature, circuitId } = await resp.json(); // Verify using ethers v5 const digest = ethers.utils.solidityKeccak256( ["uint256", "uint256", "address"], [circuitId, actionId, userAddress] ); const personalSignPreimage = ethers.utils.solidityKeccak256( ["string", "bytes32"], ["\x19Ethereum Signed Message:\n32", digest] ); const recovered = ethers.utils.recoverAddress(personalSignPreimage, signature) console.log(recovered === '0xa74772264f896843c6346ceA9B13e0128A1d3b5D')
-
Responses
-
200
{ "isUnique" : true, "signature": "0x123..." }
-
200
{ "isUnique" : false, }
-
The sybil-resistance
endpoint uses blockchain-address + action-id pairings to establish uniqueness.
We suggest that you use the default action-id 123456789
.
You can use the action-id to designate something other than an action. You could create one action-id for one part of your action and another action-id for a different part. The purpose of this is to preserve user privacy. You could, for example, require that users register for the airdrop portion of your action (one action-id) and that they register separately for voting (another action-id); by doing this, you can perform Sybil-resistant airdrops and Sybil-resistant voting without creating links between the blockchain accounts that received airdrops and the accounts that voted.