Bandada library to validate users' credentials.
This package provides a function to validate users' credentials by using a set of extendable validators. |
---|
Install the @bandada/credentials
package with npm:
npm i @bandada/credentials
or yarn:
yarn add @bandada/credentials
# validateCredentials(credentials: Credentials, context: Context): Promise<boolean>
Validates the blockchain balance of a user.
- credentials (Credentials):
- id: The id for the blockchain balance validation.
- criteria:
- minBalance: The minimum number of balance required.
- network: The blockchain network to validate against.
- blockNumber (optional): The block number at which to check the balance.
- context (Context):
- address: The blockchain address to validate.
- jsonRpcProvider: The JSON-RPC provider to use for blockchain interactions.
import {
validateCredentials,
blockchainBalance,
getProvider,
BlockchainProvider
} from "@bandada/credentials"
const provider = getProvider("blockchain")
const jsonRpcProvider = await (
provider as BlockchainProvider
).getJsonRpcProvider("https://rpc-url.com")
validateCredentials(
{
id: blockchainBalance.id,
criteria: {
minBalance: "10",
network: "sepolia",
blockNumber: 4749638
}
},
{
address: "0x",
jsonRpcProvider
}
)
# validateCredentials(credentials: Credentials, context: Context): Promise<boolean>
Validates the blockchain transactions of a user.
- credentials (Credentials):
- id: The id for the blockchain transactions validation.
- criteria:
- minTransactions: The minimum number of transactions required.
- network: The blockchain network to validate against.
- blockNumber (optional): The block number at which to check the transactions.
- context (Context):
- address: The blockchain address to validate.
- jsonRpcProvider: The JSON-RPC provider to use for blockchain interactions.
import {
validateCredentials,
blockchainTransactions,
getProvider,
BlockchainProvider
} from "@bandada/credentials"
const provider = getProvider("blockchain")
const jsonRpcProvider = await (
provider as BlockchainProvider
).getJsonRpcProvider("https://rpc-url.com")
validateCredentials(
{
id: blockchainTransactions.id,
criteria: {
minTransactions: 10,
network: "sepolia",
blockNumber: 4749638
}
},
{
address: "0x",
jsonRpcProvider
}
)
# validateCredentials(credentials: Credentials, context: Context): Promise<boolean>
Validates the EAS attestations of a user.
- credentials (Credentials):
- id: The id for the EAS attestations validation.
- criteria:
- minAttestations: The minimum number of attestations required.
- network: The id of the supported attestation network.
- attester (optional): The attester of the attestation.
- schemaId (optional): The schema id of the attestation.
- revocable (optional): The revocable option of the attestation.
- revoked (optional): The revocation status of the attestation.
- isOffchain (optional): The type of chain of the attestation.
- context (Context):
- network: The EAS network chain.
- address: The user address to validate.
import { easCredentialSupportedNetworks } from "@bandada/utils"
import {
validateCredentials,
easAttestations,
EASNetworks
} from "@bandada/credentials"
const network = easCredentialSupportedNetworks.find("sepolia")
validateCredentials(
{
id: easAttestations.id,
criteria: {
minAttestations: 1,
network: network.id,
schemaId: "0x",
attester: "0x1",
revocable: false,
revoked: false,
isOffchain: false
}
},
{
address: "0x2"
}
)
# validateCredentials(credentials: Credentials, context: Context): Promise<boolean>
Validates the number of followers of a GitHub user.
- credentials (Credentials):
- id: The id for the GitHub followers validation.
- criteria:
- minFollowers: The minimum number of GitHub followers required.
- context (Context):
- profile: The user's GitHub profile.
- accessTokens:
- github: The user's GitHub login access token.
import {
validateCredentials,
githubFollowers,
getProvider,
Web2Provider
} from "@bandada/credentials"
const provider = getProvider("github")
const accessToken = await (provider as Web2Provider).getAccessToken(
"clientId",
"clientSecret",
"oAuthCode",
"oAuthState",
"redirectUri"
)
const profile = await (provider as Web2Provider).getProfile(accessToken)
validateCredentials(
{
id: githubFollowers.id,
criteria: {
minFollowers: 100
}
},
{
profile,
accessTokens: {
github: accessToken
}
}
)
# validateCredentials(credentials: Credentials, context: Context): Promise<boolean>
Validates the number of stars in a GitHub user's personal repositories.
- credentials (Credentials):
- id: The id for the GitHub personal stars validation.
- criteria:
- minStars: The minimum number of GitHub personal stars required.
- context (Context):
- profile: The user's GitHub profile.
- accessTokens:
- github: The user's GitHub login access token.
import {
validateCredentials,
githubPersonalStars,
getProvider,
Web2Provider
} from "@bandada/credentials"
const provider = getProvider("github")
const accessToken = await (provider as Web2Provider).getAccessToken(
"clientId",
"clientSecret",
"oAuthCode",
"oAuthState",
"redirectUri"
)
const profile = await (provider as Web2Provider).getProfile(accessToken)
validateCredentials(
{
id: githubPersonalStars.id,
criteria: {
minStars: 100
}
},
{
profile,
accessTokens: {
github: accessToken
}
}
)
# validateCredentials(credentials: Credentials, context: Context): Promise<boolean>
Validates the number of commits by a GitHub user in a specific repository.
- credentials (Credentials):
- id: The id for the GitHub repository commit validation.
- criteria:
- minCommits: The minimum number of GitHub commits required.
- repository: The name of the target GitHub repository.
- context (Context):
- profile: The user's GitHub profile.
- accessTokens:
- github: The user's GitHub login access token.
import {
validateCredentials,
githubRepositoryCommits,
getProvider,
Web2Provider
} from "@bandada/credentials"
const provider = getProvider("github")
const accessToken = await (provider as Web2Provider).getAccessToken(
"clientId",
"clientSecret",
"oAuthCode",
"oAuthState",
"redirectUri"
)
const profile = await (provider as Web2Provider).getProfile(accessToken)
validateCredentials(
{
id: githubRepositoryCommits.id,
criteria: {
repository: "hello-world",
minCommits: 100
}
},
{
profile,
accessTokens: {
github: accessToken
}
}
)
# validateCredentials(credentials: Credentials, context: Context): Promise<boolean>
Validates the number of followers of a Twitter(X) user.
- credentials (Credentials):
- id: The id for the Twitter(X) followers validation.
- criteria:
- minFollowers: The minimum number of followers required.
- context (Context):
- profile: The user's Twitter(X) profile.
- accessTokens:
- github: The user's Twitter(X) login access token.
import {
validateCredentials,
twitterFollowers,
getProvider,
Web2Provider
} from "@bandada/credentials"
const provider = getProvider("twitter")
const accessToken = await (provider as Web2Provider).getAccessToken(
"clientId",
"clientSecret",
"oAuthCode",
"oAuthState",
"redirectUri"
)
const profile = await (provider as Web2Provider).getProfile(accessToken)
validateCredentials(
{
id: twitterFollowers.id,
criteria: {
minFollowers: 100
}
},
{
profile,
accessTokens: {
twitter: accessToken
}
}
)
# validateCredentials(credentials: Credentials, context: Context): Promise<boolean>
Validates whether a Twitter(X) user follows a specific user.
- credentials (Credentials):
- id: The id for the Twitter(X) following user validation.
- criteria:
- username: The username of the target Twitter(X) user.
- context (Context):
- profile: The user's Twitter(X) profile.
- accessTokens:
- github: The user's Twitter(X) login access token.
import {
validateCredentials,
twitterFollowingUser,
getProvider,
Web2Provider
} from "@bandada/credentials"
const provider = getProvider("twitter")
const accessToken = await (provider as Web2Provider).getAccessToken(
"clientId",
"clientSecret",
"oAuthCode",
"oAuthState",
"redirectUri"
)
const profile = await (provider as Web2Provider).getProfile(accessToken)
validateCredentials(
{
id: twitterFollowingUser.id,
criteria: {
username: "hello"
}
},
{
profile,
accessTokens: {
twitter: accessToken
}
}
)
# validateManyCredentials(credentials: Credentials[], context: Context[], expression: string[]): Promise<boolean>
Validates many credentials with parentheses in the expression.
- credentials (Credentials[]):
- Refer to examples above for different criteria objects.
- context (Context[]):
- Refer to examples above for different context objects.
- expressions (string[]):
- Array of string for expressions.
import {
validateManyCredentials,
blockchainBalance,
blockchainTransactions,
githubPersonalStars
} from "@bandada/credentials"
const credentials = [
{
id: blockchainBalance.id,
criteria: {
minBalance: "10",
network: "sepolia"
}
},
{
id: blockchainTransactions.id,
criteria: {
minTransactions: 10,
network: "sepolia"
}
},
{
id: githubPersonalStars.id,
criteria: {
minStars: 100
}
}
]
const contexts = [
{
address: "0x",
jsonRpcProvider
},
{
address: "0x",
jsonRpcProvider
},
{
profile: {},
accessTokens: { github: "token" }
}
]
const expression = ["", "and", "(", "", "or", "", ")"]
validateManyCredentials(credentials, contexts, expression)
The library has been built to allow external devs to add their own validators. A validator is a simple file that exports 3 JavaScript values:
id
: The validator id. It must be unique and capitalized (snake case).criteriaABI
: The criteria ABI. It contains the structure of your criteria with its types.validate
: The validator handler. It usually consists of three steps: criteria types check, user data retrieval and credentials' validation.
import { Handler } from "@bandada/credentials"
// Typescript type for the handler criteria.
// This will be mainly used by this handler.
export type Criteria = {
minFollowers: number
}
const validator: Validator = {
id: "GITHUB_FOLLOWERS",
// The criteria application binary interface. It contains
// the structure of this validator credentials
// with its parameter types.
criteriaABI: {
minFollowers: "number"
},
/**
* It checks if a user has more than 'minFollowers' followers.
* @param criteria The criteria used to check user's credentials.
* @param context Utility functions and other context variables.
* @returns True if the user meets the credentials.
*/
async validate(criteria: Criteria, { utils }) {
// Step 1: use the API to get the user's parameters.
const { followers } = await utils.api("user")
// Step 2: check if they meet the validator credentials.
return followers >= criteria.minFollowers
}
}
export default validator
Testing your validator is also important. If you use Jest you can use some test utilities to mock the API function easily.
import {
addValidator,
testUtils,
validateCredentials
} from "@bandada/credentials"
import githubFollowers from "./index"
describe("GithubFollowers", () => {
beforeAll(() => {
addValidator(githubFollowers)
})
it("Should return true if a Github user has more than 100 followers", async () => {
testUtils.mockAPIOnce({
followers: 110
})
const result = await validateCredentials(
{
id: "GITHUB_FOLLOWERS",
criteria: {
minFollowers: 100
}
},
{
accessTokens: {
github: "token"
}
}
)
expect(result).toBeTruthy()
})
})
Once you create your own validator and publish your NPM package, you can open a PR to add your validator to the ones supported by Bandada (validators.ts
file). You can also add a new provider to the providers.ts
file.