diff --git a/cspell.json b/cspell.json
index 5fd132580974..5a0d15d73443 100644
--- a/cspell.json
+++ b/cspell.json
@@ -260,7 +260,8 @@
"xlarge",
"xlink",
"zerion",
- "zubin"
+ "zubin",
+ "merkel"
],
"ignoreWords": [
"aicanft",
diff --git a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx
index 7d7ca7f8f172..f3f07d716d5e 100644
--- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx
+++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx
@@ -55,6 +55,7 @@ const useStyles = makeStyles()((theme) => ({
},
linkWrapper: {
position: 'relative',
+ display: 'block',
width: 172,
height: 172,
},
diff --git a/packages/mask/src/plugins/MaskBox/SNSAdaptor/components/PreviewCard.tsx b/packages/mask/src/plugins/MaskBox/SNSAdaptor/components/PreviewCard.tsx
index fa95b82762d4..d1bb7ccf4ae8 100644
--- a/packages/mask/src/plugins/MaskBox/SNSAdaptor/components/PreviewCard.tsx
+++ b/packages/mask/src/plugins/MaskBox/SNSAdaptor/components/PreviewCard.tsx
@@ -51,8 +51,6 @@ export function PreviewCard(props: PreviewCardProps) {
const {
boxId,
boxState,
- isQualified,
- holderToken,
boxStateMessage,
boxInfo,
boxMetadata,
@@ -198,14 +196,9 @@ export function PreviewCard(props: PreviewCardProps) {
size="medium"
fullWidth
variant="contained"
- disabled={boxState !== BoxState.READY || !isQualified}
+ disabled={boxState !== BoxState.READY}
onClick={() => setOpenDrawDialog(true)}>
{(() => {
- if (!isQualified) {
- const { symbol, decimals } = holderToken ?? {}
- const tokenPrice = `${formatBalance(boxInfo?.holderMinTokenAmount, decimals)} $${symbol}`
- return `You must hold at least ${tokenPrice}`
- }
return boxState === BoxState.READY && paymentTokenAddress ? (
<>
{boxStateMessage} (
diff --git a/packages/mask/src/plugins/MaskBox/SNSAdaptor/index.tsx b/packages/mask/src/plugins/MaskBox/SNSAdaptor/index.tsx
index bcdc72943447..3e31f89f3edc 100644
--- a/packages/mask/src/plugins/MaskBox/SNSAdaptor/index.tsx
+++ b/packages/mask/src/plugins/MaskBox/SNSAdaptor/index.tsx
@@ -32,6 +32,7 @@ export default sns
function Renderer(props: React.PropsWithChildren<{ url: string }>) {
const [, chainId] = props.url.match(/chain=(\d+)/i) ?? []
const [, boxId] = props.url.match(/box=(\d+)/i) ?? []
+ const [, hashRoot] = props.url.match(/rootHash=([\dA-Za-z]+)/) ?? []
const shouldNotRender = !chainId || !boxId
usePluginWrapper(!shouldNotRender)
@@ -39,7 +40,7 @@ function Renderer(props: React.PropsWithChildren<{ url: string }>) {
return (
-
+
diff --git a/packages/mask/src/plugins/MaskBox/apis/index.ts b/packages/mask/src/plugins/MaskBox/apis/index.ts
index d6a8c7357c73..137f34bb9057 100644
--- a/packages/mask/src/plugins/MaskBox/apis/index.ts
+++ b/packages/mask/src/plugins/MaskBox/apis/index.ts
@@ -1 +1,2 @@
export * from './rss3'
+export * from './merkleProof'
diff --git a/packages/mask/src/plugins/MaskBox/apis/merkleProof.ts b/packages/mask/src/plugins/MaskBox/apis/merkleProof.ts
new file mode 100644
index 000000000000..4a8f6637c231
--- /dev/null
+++ b/packages/mask/src/plugins/MaskBox/apis/merkleProof.ts
@@ -0,0 +1,16 @@
+import urlcat from 'urlcat'
+import { MERKLE_PROOF_ENDPOINT } from '../constants'
+
+export async function getMerkleProof(leaf: string, root: string) {
+ try {
+ const response = await fetch(
+ urlcat(MERKLE_PROOF_ENDPOINT, {
+ leaf,
+ root: root.replace(/^0x/, ''),
+ }),
+ )
+ return (await response.json()) as { proof?: string[]; message?: string; module?: string }
+ } catch (err: any) {
+ throw new Error(err?.message)
+ }
+}
diff --git a/packages/mask/src/plugins/MaskBox/constants.ts b/packages/mask/src/plugins/MaskBox/constants.ts
index 989e33b9d1f4..49e7183f3fed 100644
--- a/packages/mask/src/plugins/MaskBox/constants.ts
+++ b/packages/mask/src/plugins/MaskBox/constants.ts
@@ -2,3 +2,5 @@ import { PluginId } from '@masknet/plugin-infra'
export const PLUGIN_ID = PluginId.MaskBox
export const RSS3_ENDPOINT = 'https://hub.pass3.me'
+export const MERKLE_PROOF_ENDPOINT =
+ 'https://lf8d031acj.execute-api.ap-east-1.amazonaws.com/api/v1/merkle_tree/leaf_exists'
diff --git a/packages/mask/src/plugins/MaskBox/hooks/useContext.ts b/packages/mask/src/plugins/MaskBox/hooks/useContext.ts
index 1587d1ef676d..51579f1c95fa 100644
--- a/packages/mask/src/plugins/MaskBox/hooks/useContext.ts
+++ b/packages/mask/src/plugins/MaskBox/hooks/useContext.ts
@@ -1,4 +1,5 @@
import { useEffect, useMemo, useState, useCallback } from 'react'
+import * as ABICoder from 'web3-eth-abi'
import { useAsyncRetry } from 'react-use'
import fromUnixTime from 'date-fns/fromUnixTime'
import addDays from 'date-fns/addDays'
@@ -24,10 +25,12 @@ import {
ZERO_ADDRESS,
isZeroAddress,
isNativeTokenAddress,
+ formatBalance,
} from '@masknet/web3-shared-evm'
import type { NonPayableTx } from '@masknet/web3-contracts/types/types'
import { BoxInfo, BoxState } from '../type'
import { useMaskBoxInfo } from './useMaskBoxInfo'
+import { useMerkelProof } from './useMerkleProof'
import { useMaskBoxStatus } from './useMaskBoxStatus'
import { useMaskBoxCreationSuccessEvent } from './useMaskBoxCreationSuccessEvent'
import { useMaskBoxTokensForSale } from './useMaskBoxTokensForSale'
@@ -35,18 +38,26 @@ import { useMaskBoxPurchasedTokens } from './useMaskBoxPurchasedTokens'
import { formatCountdown } from '../helpers/formatCountdown'
import { useOpenBoxTransaction } from './useOpenBoxTransaction'
import { useMaskBoxMetadata } from './useMaskBoxMetadata'
-import { useIsWhitelisted } from './useIsWhitelisted'
-import { isGreaterThanOrEqualTo, isLessThanOrEqualTo, isZero, multipliedBy, useBeat } from '@masknet/web3-shared-base'
+import { useQualification } from './useQualification'
+import {
+ isGreaterThan,
+ isGreaterThanOrEqualTo,
+ isLessThanOrEqualTo,
+ multipliedBy,
+ useBeat,
+} from '@masknet/web3-shared-base'
-function useContext(initialState?: { boxId: string }) {
+function useContext(initialState?: { boxId: string; hashRoot: string }) {
const now = new Date()
const beat = useBeat()
const account = useAccount()
const chainId = useChainId()
const { NATIVE_TOKEN_ADDRESS } = useTokenConstants(ChainId.Mainnet)
const { MASK_BOX_CONTRACT_ADDRESS } = useMaskBoxConstants()
+ const coder = ABICoder as unknown as ABICoder.AbiCoder
const [boxId, setBoxId] = useState(initialState?.boxId ?? '')
+ const [rootHash, setRootHash] = useState(initialState?.hashRoot || '')
const [paymentTokenAddress, setPaymentTokenAddress] = useState('')
// #region the box info
@@ -56,6 +67,7 @@ function useContext(initialState?: { boxId: string }) {
loading: loadingMaskBoxInfo,
retry: retryMaskBoxInfo,
} = useMaskBoxInfo(boxId)
+
const {
value: maskBoxStatus = null,
error: errorMaskBoxStatus,
@@ -133,10 +145,37 @@ function useContext(initialState?: { boxId: string }) {
maskBoxStatus,
maskBoxCreationSuccessEvent,
])
+ // #endregion
+
+ // #region qualification
+ const { value, error: errorProof, loading: loadingProof } = useMerkelProof(rootHash)
+ const proofBytes = value?.proof
+ ? coder.encodeParameters(['bytes32[]'], [value?.proof?.map((p) => `0x${p}`) ?? []])
+ : undefined
+ const qualification = useQualification(
+ boxInfo?.qualificationAddress,
+ account,
+ value?.proof ? coder.encodeParameters(['bytes', 'bytes32'], [proofBytes, rootHash]) : undefined,
+ )
+
+ // not in whitelist
+ const notInWhiteList = value?.message === 'leaf not found'
+
+ // at least hold token amount
+ const { value: holderToken } = useERC20TokenDetailed(boxInfo?.holderTokenAddress)
+ const { value: holderTokenBalance = '0' } = useERC20TokenBalance(holderToken?.address)
+ const holderMinTokenAmountBN = new BigNumber(boxInfo?.holderMinTokenAmount ?? 0)
+ const insufficientHolderToken =
+ isGreaterThan(holderMinTokenAmountBN, 0) && !holderMinTokenAmountBN.lte(holderTokenBalance)
+ // #endregion
const boxState = useMemo(() => {
- if (errorMaskBoxInfo || errorMaskBoxStatus || errorBoxInfo) return BoxState.ERROR
- if (loadingMaskBoxInfo || loadingMaskBoxStatus || loadingBoxInfo) {
+ if (notInWhiteList) return BoxState.NOT_IN_WHITELIST
+ if (insufficientHolderToken) return BoxState.INSUFFICIENT_HOLDER_TOKEN
+ if (qualification?.error_msg) return BoxState.NOT_QUALIFIED
+ if (errorMaskBoxInfo || errorMaskBoxStatus || errorBoxInfo || (rootHash ? errorProof : false))
+ return BoxState.ERROR
+ if (loadingMaskBoxInfo || loadingMaskBoxStatus || loadingBoxInfo || (rootHash ? loadingProof : false)) {
if (!maskBoxInfo && !boxInfo) return BoxState.UNKNOWN
}
if (maskBoxInfo && !boxInfo) return BoxState.UNKNOWN
@@ -147,19 +186,21 @@ function useContext(initialState?: { boxId: string }) {
if (boxInfo.startAt > now || !boxInfo.started) return BoxState.NOT_READY
if (boxInfo.endAt < now || maskBoxStatus?.expired) return BoxState.EXPIRED
return BoxState.READY
- }, [boxInfo, loadingBoxInfo, errorBoxInfo, maskBoxInfo, loadingMaskBoxInfo, errorMaskBoxInfo, beat])
-
- const isWhitelisted = useIsWhitelisted(boxInfo?.qualificationAddress, account)
- const isQualifiedByContract =
- boxInfo?.qualificationAddress && !isZeroAddress(boxInfo?.qualificationAddress) ? isWhitelisted : true
-
- // #region check holder min token
- const { value: holderToken } = useERC20TokenDetailed(boxInfo?.holderTokenAddress)
- const { value: holderTokenBalance = '0' } = useERC20TokenBalance(holderToken?.address)
- const holderMinTokenAmountBN = new BigNumber(boxInfo?.holderMinTokenAmount ?? 0)
- const isQualified =
- (isZero(holderMinTokenAmountBN) || holderMinTokenAmountBN.lte(holderTokenBalance)) && isQualifiedByContract
- // #endregion
+ }, [
+ boxInfo,
+ loadingBoxInfo,
+ errorBoxInfo,
+ maskBoxInfo,
+ loadingMaskBoxInfo,
+ errorMaskBoxInfo,
+ qualification,
+ loadingProof,
+ errorProof,
+ rootHash,
+ notInWhiteList,
+ insufficientHolderToken,
+ beat,
+ ])
const boxStateMessage = useMemo(() => {
switch (boxState) {
@@ -179,8 +220,16 @@ function useContext(initialState?: { boxId: string }) {
return countdown ? `Start sale in ${countdown}` : 'Loading...'
case BoxState.SOLD_OUT:
return 'Sold Out'
+ case BoxState.NOT_IN_WHITELIST:
+ return 'You are not in the whitelist.'
+ case BoxState.INSUFFICIENT_HOLDER_TOKEN:
+ const { symbol, decimals } = holderToken ?? {}
+ const tokenPrice = `${formatBalance(boxInfo?.holderMinTokenAmount, decimals)} $${symbol}`
+ return `You must hold at least ${tokenPrice}.`
+ case BoxState.NOT_QUALIFIED:
+ return qualification?.error_msg ?? 'Not qualified.'
case BoxState.DRAWED_OUT:
- return 'Purchase limit exceeded'
+ return 'Purchase limit exceeded.'
case BoxState.ERROR:
return 'Something went wrong.'
case BoxState.NOT_FOUND:
@@ -188,7 +237,7 @@ function useContext(initialState?: { boxId: string }) {
default:
unreachable(boxState)
}
- }, [boxState, boxInfo?.startAt, beat])
+ }, [holderToken, boxState, boxInfo?.startAt, qualification, beat])
useEffect(() => {
if (!boxInfo || boxInfo.started) return
@@ -198,8 +247,6 @@ function useContext(initialState?: { boxId: string }) {
}
}, [boxInfo, beat])
- // #endregion
-
// #region the box metadata
const { value: boxMetadata, retry: retryBoxMetadata } = useMaskBoxMetadata(boxId, boxInfo?.creator ?? '')
// #endregion
@@ -255,13 +302,14 @@ function useContext(initialState?: { boxId: string }) {
paymentTokenIndex,
paymentTokenPrice,
paymentTokenDetailed,
+ proofBytes,
openBoxTransactionOverrides,
)
const { value: erc20Allowance, retry: retryAllowance } = useERC20TokenAllowance(
isNativeToken ? undefined : paymentTokenAddress,
MASK_BOX_CONTRACT_ADDRESS,
)
- const canPurchase = !isBalanceInsufficient && isQualified && !!boxInfo?.personalRemaining
+ const canPurchase = !isBalanceInsufficient && !!boxInfo?.personalRemaining
const allowToPurchase = boxState === BoxState.READY
const isAllowanceEnough = isNativeToken ? true : costAmount.lte(erc20Allowance ?? '0')
const { value: openBoxTransactionGasLimit } = useAsyncRetry(async () => {
@@ -276,9 +324,6 @@ function useContext(initialState?: { boxId: string }) {
boxId,
setBoxId,
- isQualified,
- holderToken,
-
// box info & metadata
boxInfo,
boxMetadata,
diff --git a/packages/mask/src/plugins/MaskBox/hooks/useIsWhitelisted.ts b/packages/mask/src/plugins/MaskBox/hooks/useIsWhitelisted.ts
deleted file mode 100644
index 022e73935bda..000000000000
--- a/packages/mask/src/plugins/MaskBox/hooks/useIsWhitelisted.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { useMemo } from 'react'
-import { useAsyncRetry } from 'react-use'
-import { useWhitelistContract } from './useWhitelistContract'
-
-export function useIsWhitelisted(address?: string, account?: string) {
- const contract = useWhitelistContract(address)
- const result = useAsyncRetry(async () => {
- if (!contract || !account) return null
- return contract.methods.is_qualified(account, '0x00').call()
- }, [account, contract])
-
- return useMemo(() => result.value ?? { qualified: false, error_msg: '' }, [result.value])
-}
diff --git a/packages/mask/src/plugins/MaskBox/hooks/useMaskBoxQualificationContract.ts b/packages/mask/src/plugins/MaskBox/hooks/useMaskBoxQualificationContract.ts
new file mode 100644
index 000000000000..b013cb1f3d64
--- /dev/null
+++ b/packages/mask/src/plugins/MaskBox/hooks/useMaskBoxQualificationContract.ts
@@ -0,0 +1,8 @@
+import type { AbiItem } from 'web3-utils'
+import { useContract } from '@masknet/web3-shared-evm'
+import type { MaskBoxQualification } from '@masknet/web3-contracts/types/MaskBoxQualification'
+import MASK_BOX_QUALIFICATION_CONTRACT from '@masknet/web3-contracts/abis/MaskBoxQualification.json'
+
+export function useMaskBoxQualificationContract(address?: string) {
+ return useContract(address, MASK_BOX_QUALIFICATION_CONTRACT as AbiItem[])
+}
diff --git a/packages/mask/src/plugins/MaskBox/hooks/useMerkleProof.ts b/packages/mask/src/plugins/MaskBox/hooks/useMerkleProof.ts
new file mode 100644
index 000000000000..3d4c0b08e22b
--- /dev/null
+++ b/packages/mask/src/plugins/MaskBox/hooks/useMerkleProof.ts
@@ -0,0 +1,16 @@
+import { useAsyncRetry } from 'react-use'
+import { useAccount } from '@masknet/web3-shared-evm'
+import { getMerkleProof } from '../apis'
+
+export function useMerkelProof(root?: string) {
+ const account = useAccount()
+ return useAsyncRetry(async () => {
+ if (!root) return
+
+ const leaf = Buffer.from(
+ (account.replace(/0x/, '').match(/.{2}/g) ?? []).map((x) => Number.parseInt(x, 16)),
+ ).toString('base64')
+
+ return getMerkleProof(leaf, root)
+ }, [account, root])
+}
diff --git a/packages/mask/src/plugins/MaskBox/hooks/useOpenBoxTransaction.ts b/packages/mask/src/plugins/MaskBox/hooks/useOpenBoxTransaction.ts
index 91f772589fe8..2a59d7016ae9 100644
--- a/packages/mask/src/plugins/MaskBox/hooks/useOpenBoxTransaction.ts
+++ b/packages/mask/src/plugins/MaskBox/hooks/useOpenBoxTransaction.ts
@@ -10,6 +10,7 @@ export function useOpenBoxTransaction(
paymentTokenIndex: number,
paymentTokenPrice: string,
paymentTokenDetailed: FungibleTokenDetailed | null,
+ proof?: string,
overrides?: NonPayableTx | null,
) {
const account = useAccount()
@@ -25,7 +26,17 @@ export function useOpenBoxTransaction(
? multipliedBy(paymentTokenPrice, amount).toFixed()
: undefined,
},
- method: maskBoxContract.methods.openBox(boxId, amount, paymentTokenIndex, '0x0'),
+ method: maskBoxContract.methods.openBox(boxId, amount, paymentTokenIndex, proof ?? '0x00'),
}
- }, [account, amount, boxId, maskBoxContract, paymentTokenIndex, paymentTokenPrice, paymentTokenDetailed, overrides])
+ }, [
+ account,
+ amount,
+ boxId,
+ maskBoxContract,
+ paymentTokenIndex,
+ paymentTokenPrice,
+ paymentTokenDetailed,
+ proof,
+ overrides,
+ ])
}
diff --git a/packages/mask/src/plugins/MaskBox/hooks/useQualification.ts b/packages/mask/src/plugins/MaskBox/hooks/useQualification.ts
new file mode 100644
index 000000000000..c409f937d8f2
--- /dev/null
+++ b/packages/mask/src/plugins/MaskBox/hooks/useQualification.ts
@@ -0,0 +1,13 @@
+import { useAsyncRetry } from 'react-use'
+import { useMaskBoxQualificationContract } from './useMaskBoxQualificationContract'
+
+export function useQualification(address?: string, account?: string, proof?: string) {
+ const qualificationContract = useMaskBoxQualificationContract(address)
+ const { value: qualification = { qualified: false, error_msg: '' } } = useAsyncRetry(async () => {
+ if (!qualificationContract || !account) return null
+ return qualificationContract.methods.is_qualified(account, proof ?? '0x00').call({
+ from: account,
+ })
+ }, [account, qualificationContract, proof])
+ return qualification
+}
diff --git a/packages/mask/src/plugins/MaskBox/hooks/useWhitelistContract.ts b/packages/mask/src/plugins/MaskBox/hooks/useWhitelistContract.ts
deleted file mode 100644
index 87423cc30cfd..000000000000
--- a/packages/mask/src/plugins/MaskBox/hooks/useWhitelistContract.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import type { AbiItem } from 'web3-utils'
-import { useContract } from '@masknet/web3-shared-evm'
-import type { MaskBoxWhiteList } from '@masknet/web3-contracts/types/MaskBoxWhiteList'
-import MASK_BOX_WHITELIST_ABI from '@masknet/web3-contracts/abis/MaskBoxWhiteList.json'
-
-export function useWhitelistContract(address?: string) {
- return useContract(address, MASK_BOX_WHITELIST_ABI as AbiItem[])
-}
diff --git a/packages/mask/src/plugins/MaskBox/type.ts b/packages/mask/src/plugins/MaskBox/type.ts
index 3e0bb2b64368..ac12d96c65a3 100644
--- a/packages/mask/src/plugins/MaskBox/type.ts
+++ b/packages/mask/src/plugins/MaskBox/type.ts
@@ -20,6 +20,12 @@ export enum BoxState {
ERROR = 7,
/** 404 */
NOT_FOUND = 8,
+ /** leaf not found */
+ NOT_IN_WHITELIST = 9,
+ /** insufficient holder token */
+ INSUFFICIENT_HOLDER_TOKEN = 10,
+ /** not qualified */
+ NOT_QUALIFIED = 11,
}
export interface PaymentOption {
diff --git a/packages/web3-contracts/abis/MaskBox.json b/packages/web3-contracts/abis/MaskBox.json
index c2edd9713d53..f70d7f424344 100644
--- a/packages/web3-contracts/abis/MaskBox.json
+++ b/packages/web3-contracts/abis/MaskBox.json
@@ -311,6 +311,11 @@
"internalType": "uint256",
"name": "holder_min_token_amount",
"type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "qualification_data",
+ "type": "bytes32"
}
],
"name": "createBox",
@@ -362,6 +367,11 @@
"internalType": "uint256",
"name": "holder_min_token_amount",
"type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "qualification_data",
+ "type": "bytes32"
}
],
"stateMutability": "view",
@@ -529,6 +539,19 @@
"stateMutability": "view",
"type": "function"
},
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "addrs",
+ "type": "address[]"
+ }
+ ],
+ "name": "removeAdmin",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
{
"inputs": [
{
@@ -549,6 +572,24 @@
"stateMutability": "nonpayable",
"type": "function"
},
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "box_id",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "qualification_data",
+ "type": "bytes32"
+ }
+ ],
+ "name": "setQualificationData",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
{
"inputs": [
{
diff --git a/packages/web3-contracts/abis/MaskBoxQualification.json b/packages/web3-contracts/abis/MaskBoxQualification.json
new file mode 100644
index 000000000000..c63ad4479e30
--- /dev/null
+++ b/packages/web3-contracts/abis/MaskBoxQualification.json
@@ -0,0 +1,23 @@
+[
+ { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" },
+ {
+ "inputs": [
+ { "internalType": "address", "name": "account", "type": "address" },
+ { "internalType": "bytes", "name": "proof", "type": "bytes" }
+ ],
+ "name": "is_qualified",
+ "outputs": [
+ { "internalType": "bool", "name": "qualified", "type": "bool" },
+ { "internalType": "string", "name": "error_msg", "type": "string" }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "version",
+ "outputs": [{ "internalType": "uint32", "name": "", "type": "uint32" }],
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
diff --git a/packages/web3-contracts/abis/MaskBoxWhiteList.json b/packages/web3-contracts/abis/MaskBoxWhiteList.json
deleted file mode 100644
index 61a76e7558d6..000000000000
--- a/packages/web3-contracts/abis/MaskBoxWhiteList.json
+++ /dev/null
@@ -1,148 +0,0 @@
-[
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "previousOwner",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "address",
- "name": "newOwner",
- "type": "address"
- }
- ],
- "name": "OwnershipTransferred",
- "type": "event"
- },
- {
- "inputs": [
- {
- "internalType": "address[]",
- "name": "addrs",
- "type": "address[]"
- }
- ],
- "name": "add_white_list",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "initialize",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "account",
- "type": "address"
- },
- {
- "internalType": "bytes",
- "name": "",
- "type": "bytes"
- }
- ],
- "name": "is_qualified",
- "outputs": [
- {
- "internalType": "bool",
- "name": "qualified",
- "type": "bool"
- },
- {
- "internalType": "string",
- "name": "error_msg",
- "type": "string"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "owner",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address[]",
- "name": "addrs",
- "type": "address[]"
- }
- ],
- "name": "remove_white_list",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "renounceOwnership",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "newOwner",
- "type": "address"
- }
- ],
- "name": "transferOwnership",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "version",
- "outputs": [
- {
- "internalType": "uint32",
- "name": "",
- "type": "uint32"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "name": "white_list",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- }
-]
diff --git a/packages/web3-contracts/types/MaskBox.d.ts b/packages/web3-contracts/types/MaskBox.d.ts
index ab54e03fa2c7..6b284cf8995b 100644
--- a/packages/web3-contracts/types/MaskBox.d.ts
+++ b/packages/web3-contracts/types/MaskBox.d.ts
@@ -103,6 +103,7 @@ export interface MaskBox extends BaseContract {
qualification: string,
holder_token_addr: string,
holder_min_token_amount: number | string | BN,
+ qualification_data: string | number[],
): NonPayableTransactionObject
getBoxInfo(box_id: number | string | BN): NonPayableTransactionObject<{
@@ -113,6 +114,7 @@ export interface MaskBox extends BaseContract {
qualification: string
holder_token_addr: string
holder_min_token_amount: string
+ qualification_data: string
0: string
1: string
2: string
@@ -120,6 +122,7 @@ export interface MaskBox extends BaseContract {
4: string
5: string
6: string
+ 7: string
}>
getBoxStatus(box_id: number | string | BN): NonPayableTransactionObject<{
@@ -156,10 +159,17 @@ export interface MaskBox extends BaseContract {
owner(): NonPayableTransactionObject
+ removeAdmin(addrs: string[]): NonPayableTransactionObject
+
removeWhitelist(addrs: string[]): NonPayableTransactionObject
renounceOwnership(): NonPayableTransactionObject
+ setQualificationData(
+ box_id: number | string | BN,
+ qualification_data: string | number[],
+ ): NonPayableTransactionObject
+
transferOwnership(newOwner: string): NonPayableTransactionObject
whitelist(arg0: string): NonPayableTransactionObject
diff --git a/packages/web3-contracts/types/MaskBoxQualification.d.ts b/packages/web3-contracts/types/MaskBoxQualification.d.ts
new file mode 100644
index 000000000000..b99d14ee4331
--- /dev/null
+++ b/packages/web3-contracts/types/MaskBoxQualification.d.ts
@@ -0,0 +1,43 @@
+/* Autogenerated file. Do not edit manually. */
+/* tslint:disable */
+/* eslint-disable */
+
+import BN from 'bn.js'
+import { ContractOptions } from 'web3-eth-contract'
+import { EventLog } from 'web3-core'
+import { EventEmitter } from 'events'
+import {
+ Callback,
+ PayableTransactionObject,
+ NonPayableTransactionObject,
+ BlockType,
+ ContractEventLog,
+ BaseContract,
+} from './types'
+
+interface EventOptions {
+ filter?: object
+ fromBlock?: BlockType
+ topics?: string[]
+}
+
+export interface MaskBoxQualification extends BaseContract {
+ constructor(jsonInterface: any[], address?: string, options?: ContractOptions): MaskBoxQualification
+ clone(): MaskBoxQualification
+ methods: {
+ is_qualified(
+ account: string,
+ proof: string | number[],
+ ): NonPayableTransactionObject<{
+ qualified: boolean
+ error_msg: string
+ 0: boolean
+ 1: string
+ }>
+
+ version(): NonPayableTransactionObject
+ }
+ events: {
+ allEvents(options?: EventOptions, cb?: Callback): EventEmitter
+ }
+}
diff --git a/packages/web3-contracts/types/MaskBoxWhiteList.d.ts b/packages/web3-contracts/types/MaskBoxWhiteList.d.ts
deleted file mode 100644
index 705870d77875..000000000000
--- a/packages/web3-contracts/types/MaskBoxWhiteList.d.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Autogenerated file. Do not edit manually. */
-/* tslint:disable */
-/* eslint-disable */
-
-import BN from 'bn.js'
-import { ContractOptions } from 'web3-eth-contract'
-import { EventLog } from 'web3-core'
-import { EventEmitter } from 'events'
-import {
- Callback,
- PayableTransactionObject,
- NonPayableTransactionObject,
- BlockType,
- ContractEventLog,
- BaseContract,
-} from './types'
-
-interface EventOptions {
- filter?: object
- fromBlock?: BlockType
- topics?: string[]
-}
-
-export type OwnershipTransferred = ContractEventLog<{
- previousOwner: string
- newOwner: string
- 0: string
- 1: string
-}>
-
-export interface MaskBoxWhiteList extends BaseContract {
- constructor(jsonInterface: any[], address?: string, options?: ContractOptions): MaskBoxWhiteList
- clone(): MaskBoxWhiteList
- methods: {
- add_white_list(addrs: string[]): NonPayableTransactionObject
-
- initialize(): NonPayableTransactionObject
-
- is_qualified(
- account: string,
- arg1: string | number[],
- ): NonPayableTransactionObject<{
- qualified: boolean
- error_msg: string
- 0: boolean
- 1: string
- }>
-
- owner(): NonPayableTransactionObject
-
- remove_white_list(addrs: string[]): NonPayableTransactionObject
-
- renounceOwnership(): NonPayableTransactionObject
-
- transferOwnership(newOwner: string): NonPayableTransactionObject
-
- version(): NonPayableTransactionObject
-
- white_list(arg0: string): NonPayableTransactionObject
- }
- events: {
- OwnershipTransferred(cb?: Callback): EventEmitter
- OwnershipTransferred(options?: EventOptions, cb?: Callback): EventEmitter
-
- allEvents(options?: EventOptions, cb?: Callback): EventEmitter
- }
-
- once(event: 'OwnershipTransferred', cb: Callback): void
- once(event: 'OwnershipTransferred', options: EventOptions, cb: Callback): void
-}