mirror of
https://github.com/Brotocol-xyz/bro-sdk.git
synced 2026-01-12 14:54:21 +08:00
feat: upgrade stacks contracts
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { generateContracts } from "clarity-codegen/lib/generate"
|
||||
import * as path from "node:path"
|
||||
import {
|
||||
contractNameOverrides,
|
||||
envName,
|
||||
contractNameOverrides_mainnet,
|
||||
contractNameOverrides_testnet,
|
||||
STACKS_MAINNET,
|
||||
STACKS_TESTNET,
|
||||
} from "../src/config"
|
||||
@@ -13,6 +13,9 @@ import {
|
||||
xlinkContractsMultisigTestnet,
|
||||
} from "../src/stacksUtils/stxContractAddresses"
|
||||
import { KnownChainId } from "../src/utils/types/knownIds"
|
||||
|
||||
const envName = process.env.ENV_NAME === "dev" ? "dev" : "prod"
|
||||
|
||||
;(async function main(): Promise<void> {
|
||||
const stacksChainId =
|
||||
envName === "prod"
|
||||
@@ -47,6 +50,8 @@ import { KnownChainId } from "../src/utils/types/knownIds"
|
||||
path.resolve(__dirname, "../generated/smartContract/"),
|
||||
"xlink",
|
||||
"../smartContractHelpers/codegenImport",
|
||||
contractNameOverrides,
|
||||
envName === "prod"
|
||||
? contractNameOverrides_mainnet
|
||||
: contractNameOverrides_testnet,
|
||||
)
|
||||
})().catch(console.error)
|
||||
|
||||
@@ -9,16 +9,32 @@ export const STACKS_TESTNET = new StacksMocknet({
|
||||
url: "https://nakamoto-dev-api.alexlab.co",
|
||||
})
|
||||
|
||||
export const envName = process.env.ENV_NAME === "dev" ? "dev" : "prod"
|
||||
export const contractNameOverrides: Record<string, string> =
|
||||
envName === "prod"
|
||||
? {
|
||||
"btc-peg-in-endpoint-v2-07-swap": "btc-peg-in-v2-07-swap",
|
||||
"meta-peg-in-endpoint-v2-06-swap": "meta-peg-in-v2-06-swap",
|
||||
}
|
||||
: {
|
||||
"btc-peg-in-endpoint-v2-07-swap": "btc-peg-in-v2-07-swap-01",
|
||||
"meta-peg-in-endpoint-v2-06-swap": "meta-peg-in-v2-06-swap-01",
|
||||
"meta-peg-out-endpoint-v2-04": "meta-peg-out-endpoint-v2-04-da",
|
||||
"token-wvliabtc": "token-wvliabtc-da",
|
||||
}
|
||||
export const contractNameOverrides_mainnet: Record<string, string> = {
|
||||
"btc-peg-in-endpoint-v2-07-swap": "btc-peg-in-v2-07-swap",
|
||||
"meta-peg-in-endpoint-v2-06-swap": "meta-peg-in-v2-06-swap",
|
||||
}
|
||||
export const contractNameOverrides_testnet: Record<string, string> = {
|
||||
"token-wliabtc": "token-wliabtc-dc",
|
||||
"token-wvliabtc": "token-wvliabtc-dc",
|
||||
"token-liabtc": "token-liabtc-dc",
|
||||
"token-vliabtc": "token-vliabtc-dc",
|
||||
|
||||
// btc bridge
|
||||
"btc-peg-in-endpoint-v2-05": "btc-peg-in-endpoint-v2-05-dc",
|
||||
"btc-peg-in-endpoint-v2-07-swap": "btc-peg-in-v2-07-swap-01",
|
||||
"btc-peg-in-endpoint-v2-05-lisa": "btc-peg-in-endpoint-v2-05-lisa-dc",
|
||||
"btc-peg-in-endpoint-v2-05-launchpad": "btc-peg-in-v2-05-launchpad-dc",
|
||||
"btc-peg-out-endpoint-v2-01": "btc-peg-out-endpoint-v2-05-dc",
|
||||
// meta bridge
|
||||
"meta-peg-in-endpoint-v2-04": "meta-peg-in-endpoint-v2-04-dc",
|
||||
"meta-peg-in-endpoint-v2-06-swap": "meta-peg-in-v2-06-swap-01",
|
||||
"meta-peg-in-endpoint-v2-04-lisa": "meta-peg-in-endpoint-v2-04-lisa-dc",
|
||||
"meta-peg-out-endpoint-v2-04": "meta-peg-out-endpoint-v2-04-dc",
|
||||
// cross bridge
|
||||
"cross-peg-in-endpoint-v2-04": "cross-peg-in-endpoint-v2-04-dc",
|
||||
"cross-peg-in-endpoint-v2-04-swap": "cross-peg-in-v2-04-swap-da",
|
||||
"cross-peg-in-endpoint-v2-04-launchpad":
|
||||
"cross-peg-in-endpoint-v2-04-launchpad-dc",
|
||||
// cross router
|
||||
"cross-router-v2-03": "cross-router-v2-03-dc",
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { contractNameOverrides } from "../config"
|
||||
import {
|
||||
contractNameOverrides_mainnet,
|
||||
contractNameOverrides_testnet,
|
||||
} from "../config"
|
||||
import { KnownRoute_FromStacks_ToEVM } from "../utils/buildSupportedRoutes"
|
||||
import { assertExclude, checkNever } from "../utils/typeHelpers"
|
||||
import { KnownChainId, KnownTokenId } from "../utils/types/knownIds"
|
||||
@@ -33,8 +36,13 @@ export const legacyAlexContractDeployerTestnet =
|
||||
"ST1J2JTYXGRMZYNKE40GM87ZCACSPSSEEQVSNB7DC"
|
||||
|
||||
const wrapContractAddress = (
|
||||
network: "mainnet" | "testnet",
|
||||
address: StacksContractAddress,
|
||||
): StacksContractAddress => {
|
||||
const contractNameOverrides =
|
||||
network === "mainnet"
|
||||
? contractNameOverrides_mainnet
|
||||
: contractNameOverrides_testnet
|
||||
const contractName =
|
||||
(contractNameOverrides as any)?.[address.contractName] ??
|
||||
address.contractName
|
||||
@@ -57,81 +65,81 @@ export enum StacksContractName {
|
||||
|
||||
export const stxContractAddresses = {
|
||||
[StacksContractName.BTCPegInEndpoint]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: StacksContractName.BTCPegInEndpoint,
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsMultisigTestnet,
|
||||
contractName: StacksContractName.BTCPegInEndpoint,
|
||||
}),
|
||||
},
|
||||
[StacksContractName.BTCPegInEndpointSwap]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: StacksContractName.BTCPegInEndpointSwap,
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsMultisigTestnet,
|
||||
contractName: StacksContractName.BTCPegInEndpointSwap,
|
||||
}),
|
||||
},
|
||||
[StacksContractName.BTCPegOutEndpoint]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsDeployerMainnet,
|
||||
contractName: StacksContractName.BTCPegOutEndpoint,
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsDeployerTestnet,
|
||||
contractName: StacksContractName.BTCPegOutEndpoint,
|
||||
}),
|
||||
},
|
||||
[StacksContractName.EVMPegInEndpoint]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: StacksContractName.EVMPegInEndpoint,
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsMultisigTestnet,
|
||||
contractName: StacksContractName.EVMPegInEndpoint,
|
||||
}),
|
||||
},
|
||||
[StacksContractName.EVMPegOutEndpoint]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsDeployerMainnet,
|
||||
contractName: StacksContractName.EVMPegOutEndpoint,
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsDeployerTestnet,
|
||||
contractName: StacksContractName.EVMPegOutEndpoint,
|
||||
}),
|
||||
},
|
||||
[StacksContractName.MetaPegInEndpoint]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: StacksContractName.MetaPegInEndpoint,
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsMultisigTestnet,
|
||||
contractName: StacksContractName.MetaPegInEndpoint,
|
||||
}),
|
||||
},
|
||||
[StacksContractName.MetaPegInEndpointSwap]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: StacksContractName.MetaPegInEndpointSwap,
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsMultisigTestnet,
|
||||
contractName: StacksContractName.MetaPegInEndpointSwap,
|
||||
}),
|
||||
},
|
||||
[StacksContractName.MetaPegOutEndpoint]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: StacksContractName.MetaPegOutEndpoint,
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsMultisigTestnet,
|
||||
contractName: StacksContractName.MetaPegOutEndpoint,
|
||||
}),
|
||||
@@ -146,111 +154,111 @@ export const stxTokenContractAddresses: Record<
|
||||
Record<KnownChainId.StacksChain, StacksContractAddress>
|
||||
> = {
|
||||
[KnownTokenId.Stacks.ALEX]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: alexContractDeployerMainnet,
|
||||
contractName: "token-alex",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: alexContractDeployerTestnet,
|
||||
contractName: "token-alex",
|
||||
}),
|
||||
},
|
||||
[KnownTokenId.Stacks.aBTC]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsDeployerMainnet,
|
||||
contractName: "token-abtc",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsDeployerTestnet,
|
||||
contractName: "token-abtc",
|
||||
}),
|
||||
},
|
||||
[KnownTokenId.Stacks.sUSDT]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsDeployerMainnet,
|
||||
contractName: "token-susdt",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsDeployerTestnet,
|
||||
contractName: "token-susdt",
|
||||
}),
|
||||
},
|
||||
[KnownTokenId.Stacks.sLUNR]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsDeployerMainnet,
|
||||
contractName: "token-slunr",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsDeployerTestnet,
|
||||
contractName: "token-slunr",
|
||||
}),
|
||||
},
|
||||
[KnownTokenId.Stacks.sSKO]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsDeployerMainnet,
|
||||
contractName: "token-ssko",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsDeployerTestnet,
|
||||
contractName: "token-ssko",
|
||||
}),
|
||||
},
|
||||
[KnownTokenId.Stacks.vLiSTX]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: alexContractDeployerMainnet,
|
||||
contractName: "token-wvlqstx",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: alexContractDeployerTestnet,
|
||||
contractName: "token-wvlqstx",
|
||||
}),
|
||||
},
|
||||
[KnownTokenId.Stacks.vLiALEX]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: alexContractDeployerMainnet,
|
||||
contractName: "token-wvlialex",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: alexContractDeployerTestnet,
|
||||
contractName: "token-wvlialex",
|
||||
}),
|
||||
},
|
||||
[KnownTokenId.Stacks.vLiaBTC]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: alexContractMultisigMainnet,
|
||||
contractName: "token-wvliabtc",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: alexContractDeployerTestnet,
|
||||
contractName: "token-wvliabtc",
|
||||
}),
|
||||
},
|
||||
[KnownTokenId.Stacks.uBTC]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: "token-ubtc",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsDeployerTestnet,
|
||||
contractName: "token-ubtc",
|
||||
}),
|
||||
},
|
||||
[KnownTokenId.Stacks.DB20]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: legacyAlexContractDeployerMainnet,
|
||||
contractName: "brc20-db20",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: legacyAlexContractDeployerTestnet,
|
||||
contractName: "brc20-db20",
|
||||
}),
|
||||
},
|
||||
[KnownTokenId.Stacks.DOG]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: legacyAlexContractDeployerMainnet,
|
||||
contractName: "runes-dog",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: legacyAlexContractDeployerTestnet,
|
||||
contractName: "runes-dog",
|
||||
}),
|
||||
@@ -259,54 +267,54 @@ export const stxTokenContractAddresses: Record<
|
||||
|
||||
const terminatingStacksTokenContractAddresses = {
|
||||
wbtc: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: "token-wbtc",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsDeployerTestnet,
|
||||
contractName: "token-wbtc",
|
||||
}),
|
||||
},
|
||||
btcb: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: "token-wbtc",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsDeployerTestnet,
|
||||
contractName: "token-btcb",
|
||||
}),
|
||||
},
|
||||
cbBTC: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: "token-wbtc",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsDeployerTestnet,
|
||||
contractName: "token-wbtc",
|
||||
}),
|
||||
},
|
||||
usdt: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: "token-usdt",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress({
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsDeployerTestnet,
|
||||
contractName: "token-usdt",
|
||||
}),
|
||||
},
|
||||
usdc: {
|
||||
[KnownChainId.Stacks.Mainnet]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: "token-usdt",
|
||||
},
|
||||
[KnownChainId.Stacks.Testnet]: {
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsDeployerTestnet,
|
||||
contractName: "token-usdt",
|
||||
},
|
||||
}),
|
||||
},
|
||||
} satisfies Record<
|
||||
string,
|
||||
|
||||
@@ -45,16 +45,6 @@ export const numberToStacksContractNumber = (
|
||||
)
|
||||
}
|
||||
|
||||
// const _composeTxXLINK = composeTxOptionsFactory(xlinkContracts, {})
|
||||
// export const composeTxXLINK: typeof _composeTxXLINK = (...args) => {
|
||||
// const res = _composeTxXLINK(...args)
|
||||
// return {
|
||||
// ...res,
|
||||
// contractName:
|
||||
// (contractNameOverrides as any)?.[res.contractName] ?? res.contractName,
|
||||
// }
|
||||
// }
|
||||
|
||||
export const composeTxXLINK = composeTxOptionsFactory(xlinkContracts, {})
|
||||
|
||||
export const executeReadonlyCallXLINK = executeReadonlyCallFactory(
|
||||
|
||||
Reference in New Issue
Block a user