mirror of
https://github.com/AtHeartEngineering/bandada.git
synced 2026-01-10 13:18:33 -05:00
Merge pull request #449 from bandada-infra/ref/blockchain-validators
Make `network` part of blockchain validator criteria
This commit is contained in:
@@ -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=
|
||||
|
||||
@@ -21,8 +21,7 @@ export class CredentialsController {
|
||||
return this.credentialsService.addMember(
|
||||
dto.oAuthState,
|
||||
dto.oAuthCode,
|
||||
dto.address,
|
||||
dto.network
|
||||
dto.address
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -11,12 +11,4 @@ export class AddMemberDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
readonly address: string
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
readonly network: string
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
readonly blockNumber: string
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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={
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
24
libs/utils/src/getSupportedNetworks.ts
Normal file
24
libs/utils/src/getSupportedNetworks.ts
Normal 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"
|
||||
}
|
||||
]
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -7,3 +7,8 @@ export type OnchainBandadaGroup = {
|
||||
id: BigInt
|
||||
fingerprint: BigInt
|
||||
}
|
||||
|
||||
export type BlockchainNetwork = {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user