Merge pull request #449 from bandada-infra/ref/blockchain-validators

Make `network` part of blockchain validator criteria
This commit is contained in:
Vivian Plasencia
2024-03-28 12:02:32 +01:00
committed by GitHub
15 changed files with 149 additions and 70 deletions

View File

@@ -23,4 +23,11 @@ TWITTER_REDIRECT_URI=
TWITTER_CLIENT_ID=
TWITTER_CLIENT_SECRET=
BLOCKCHAIN_SEPOLIA_RPC_URL=
# The network name must be the same as the id that appears in the `blockchainCredentialSupportedNetworks` list
# exported from the `@bandada/utils` package but with capital letters. E.g. polygon_mumbai would be POLYGON_MUMBAI.
SEPOLIA_RPC_URL=
POLYGON_MUMBAI_RPC_URL=
OPTIMISM_SEPOLIA_RPC_URL=
ARBITRUM_SEPOLIA_RPC_URL=
AVALANCHE_C_CHAIN_FUJI_RPC_URL=

View File

@@ -21,8 +21,7 @@ export class CredentialsController {
return this.credentialsService.addMember(
dto.oAuthState,
dto.oAuthCode,
dto.address,
dto.network
dto.address
)
}
}

View File

@@ -18,7 +18,13 @@ jest.mock("@bandada/utils", () => ({
logs: ["1"]
}),
getGroups: () => []
})
}),
blockchainCredentialSupportedNetworks: [
{
id: "sepolia",
name: "Sepolia"
}
]
}))
jest.mock("@bandada/credentials", () => ({
@@ -293,7 +299,8 @@ describe("CredentialsService", () => {
credentials: JSON.stringify({
id: "BLOCKCHAIN_TRANSACTIONS",
criteria: {
minTransactions: 12
minTransactions: 12,
network: "sepolia"
}
})
},
@@ -311,8 +318,7 @@ describe("CredentialsService", () => {
const clientRedirectUri = await credentialsService.addMember(
_stateId,
undefined,
"0x",
"sepolia"
"0x"
)
expect(clientRedirectUri).toBeUndefined()
@@ -328,8 +334,7 @@ describe("CredentialsService", () => {
const clientRedirectUri = await credentialsService.addMember(
_stateId,
undefined,
"0x1",
"sepolia"
"0x1"
)
expect(clientRedirectUri).toBeUndefined()

View File

@@ -7,6 +7,7 @@ import {
Web2Context,
BlockchainContext
} from "@bandada/credentials"
import { blockchainCredentialSupportedNetworks } from "@bandada/utils"
import { id } from "@ethersproject/hash"
import {
BadRequestException,
@@ -78,15 +79,12 @@ export class CredentialsService {
* @param OAuthState OAuth state to prevent forgery attacks.
* @param oAuthCode OAuth code to exchange for an access token.
* @param address Account address.
* @param network Network name.
* @param blockNumber Block number.
* @returns Redirect URI
*/
async addMember(
oAuthState: string,
oAuthCode?: string,
address?: string,
network?: string
address?: string
): Promise<string> {
if (!this.oAuthState.has(oAuthState)) {
throw new BadRequestException(`OAuth state does not exist`)
@@ -108,10 +106,19 @@ export class CredentialsService {
let context: Web2Context | BlockchainContext
if (address) {
const { network } = JSON.parse(group.credentials).criteria
const supportedNetwork = blockchainCredentialSupportedNetworks.find(
(n) => n.name.toLowerCase() === network.toLowerCase()
)
if (supportedNetwork === undefined)
throw new BadRequestException(`The network is not supported`)
const networkEnvVariableName = supportedNetwork.id.toUpperCase()
const web3providerRpcURL =
process.env[
`${providerName.toUpperCase()}_${network.toUpperCase()}_RPC_URL`
]
process.env[`${networkEnvVariableName}_RPC_URL`]
const jsonRpcProvider = await (
provider as BlockchainProvider

View File

@@ -11,12 +11,4 @@ export class AddMemberDto {
@IsOptional()
@IsString()
readonly address: string
@IsOptional()
@IsString()
readonly network: string
@IsOptional()
@IsString()
readonly blockNumber: string
}

View File

@@ -202,9 +202,7 @@ export async function setOAuthState(
export async function addMemberByCredentials(
oAuthState: string,
oAuthCode?: string,
address?: string,
network?: string,
blockNumber?: string
address?: string
): Promise<string | null> {
try {
return await request(`${API_URL}/credentials`, {
@@ -212,9 +210,7 @@ export async function addMemberByCredentials(
data: {
oAuthState,
oAuthCode,
address,
network,
blockNumber
address
}
})
} catch (error: any) {

View File

@@ -1,4 +1,5 @@
import { validators } from "@bandada/credentials"
import { blockchainCredentialSupportedNetworks } from "@bandada/utils"
import {
Box,
Button,
@@ -198,31 +199,62 @@ export default function AccessModeStep({
</NumberInputStepper>
</NumberInput>
)}
{parameter[1].type === "string" && (
<Input
size="lg"
value={
_credentials.criteria[
parameter[0]
]
}
onChange={(event) =>
setCredentials({
..._credentials,
criteria: {
..._credentials.criteria,
[parameter[0]]:
event.target.value
}
})
}
placeholder={
parameter[0] === "repository"
? "<repo-owner>/<repo-name>"
: undefined
}
/>
)}
{parameter[0] !== "network" &&
parameter[1].type === "string" && (
<Input
size="lg"
value={
_credentials.criteria[
parameter[0]
]
}
onChange={(event) =>
setCredentials({
..._credentials,
criteria: {
..._credentials.criteria,
[parameter[0]]:
event.target
.value
}
})
}
placeholder={
parameter[0] ===
"repository"
? "<repo-owner>/<repo-name>"
: undefined
}
/>
)}
{parameter[0] === "network" &&
parameter[1].type === "string" && (
<Select
size="lg"
placeholder="Select network"
onChange={(event) =>
setCredentials({
..._credentials,
criteria: {
..._credentials.criteria,
[parameter[0]]:
event.target
.value
}
})
}
>
{blockchainCredentialSupportedNetworks.map(
(network: any) => (
<option
value={network.name}
>
{network.name}
</option>
)
)}
</Select>
)}
{parameter[1].type === "boolean" && (
<Checkbox
isChecked={

View File

@@ -40,8 +40,6 @@ export default function CredentialsPage() {
const providerName = _searchParams.get("provider")
const clientRedirectUri =
_searchParams.get("redirect_uri") || undefined
const network = _searchParams.get("network")
const blockNumber = _searchParams.get("block")
const state = await setOAuthState(
groupId as string,
@@ -57,17 +55,11 @@ export default function CredentialsPage() {
isLoggedInAdmin() &&
state
) {
let blockNumberVal
if (blockNumber) {
blockNumberVal = blockNumber
}
if (state && admin && network) {
if (state && admin) {
const redirectUrl = await addMemberByCredentials(
state,
undefined,
admin.address,
network,
blockNumberVal
admin.address
)
if (redirectUrl) {

View File

@@ -14,7 +14,8 @@ describe("BlockchainBalance", () => {
{
id: blockchainBalance.id,
criteria: {
minBalance: "10"
minBalance: "10",
network: "sepolia"
}
},
{
@@ -34,6 +35,7 @@ describe("BlockchainBalance", () => {
id: blockchainBalance.id,
criteria: {
minBalance: "10",
network: "sepolia",
blockNumber: 4749638
}
},
@@ -71,6 +73,7 @@ describe("BlockchainBalance", () => {
id: blockchainBalance.id,
criteria: {
minBalance: "100",
network: "sepolia",
minStars: 200
}
},
@@ -91,7 +94,8 @@ describe("BlockchainBalance", () => {
{
id: blockchainBalance.id,
criteria: {
minBalance: 100
minBalance: 100,
network: "sepolia"
}
},
{

View File

@@ -3,6 +3,7 @@ import { BlockchainContext, Validator } from "../.."
export type Criteria = {
minBalance: string
network: string
blockNumber?: number
}
@@ -14,6 +15,10 @@ const validator: Validator = {
type: "string",
optional: false
},
network: {
type: "string",
optional: false
},
blockNumber: {
type: "number",
optional: true

View File

@@ -13,7 +13,8 @@ describe("BlockchainTransactions", () => {
{
id: blockchainTransactions.id,
criteria: {
minTransactions: 10
minTransactions: 10,
network: "sepolia"
}
},
{
@@ -33,6 +34,7 @@ describe("BlockchainTransactions", () => {
id: blockchainTransactions.id,
criteria: {
minTransactions: 10,
network: "sepolia",
blockNumber: 4749638
}
},
@@ -70,6 +72,7 @@ describe("BlockchainTransactions", () => {
id: blockchainTransactions.id,
criteria: {
minTransactions: 100,
network: "sepolia",
minStars: 200
}
},
@@ -90,7 +93,8 @@ describe("BlockchainTransactions", () => {
{
id: blockchainTransactions.id,
criteria: {
minTransactions: "100"
minTransactions: "100",
network: "sepolia"
}
},
{

View File

@@ -2,6 +2,7 @@ import { BlockchainContext, Validator } from "../.."
export type Criteria = {
minTransactions: number
network: string
blockNumber?: number
}
@@ -13,6 +14,10 @@ const validator: Validator = {
type: "number",
optional: false
},
network: {
type: "string",
optional: false
},
blockNumber: {
type: "number",
optional: true

View File

@@ -0,0 +1,24 @@
import type { BlockchainNetwork } from "./types"
export const blockchainCredentialSupportedNetworks: BlockchainNetwork[] = [
{
id: "sepolia",
name: "Sepolia"
},
{
id: "polygon_mumbai",
name: "Polygon Mumbai"
},
{
id: "optimism_sepolia",
name: "Optimism Sepolia"
},
{
id: "arbitrum_sepolia",
name: "Arbitrum Sepolia"
},
{
id: "avalanche_c_chain_fuji",
name: "Avalanche C-Chain Fuji"
}
]

View File

@@ -8,6 +8,7 @@ import getWallet from "./getWallet"
import getBandadaContract, { BandadaContract } from "./getBandadaContract"
import request from "./request"
import shortenAddress from "./shortenAddress"
import { blockchainCredentialSupportedNetworks } from "./getSupportedNetworks"
export * from "./types/index"
export {
@@ -23,5 +24,6 @@ export {
CONTRACT_ADDRESSES,
getContractAddresses,
SemaphoreABI,
BandadaABI
BandadaABI,
blockchainCredentialSupportedNetworks
}

View File

@@ -7,3 +7,8 @@ export type OnchainBandadaGroup = {
id: BigInt
fingerprint: BigInt
}
export type BlockchainNetwork = {
id: string
name: string
}