From 8a16ff974d173ef835bb86ea862e7603a28c2c45 Mon Sep 17 00:00:00 2001 From: Franklin Date: Thu, 26 Jun 2025 22:09:05 +0100 Subject: [PATCH 01/19] Main (#81) * fix var issue (#80) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) Co-authored-by: Franklin Nwanze * Update blockchain.ts * Update blockchain.ts * fix bug (#78) (#79) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) * Update blockchain.ts * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * log to check error * changes to backend * added deploy script * added deploy script --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> --- backend-all/package.json | 4 +- backend-all/src/gotbit-tools/node/rpc.ts | 25 +++++----- backend-all/src/services/blockchain.ts | 1 + backend-all/src/utils/env-var.ts | 10 ++++ .../mainnet/asset-chain/12_XRWA.deploy.ts | 50 +++++++++++++++++++ .../testnet/asset-chain/12_XRWA.deploy.ts | 50 +++++++++++++++++++ 6 files changed, 127 insertions(+), 13 deletions(-) create mode 100644 backend-all/src/utils/env-var.ts create mode 100644 contracts/deploy/mainnet/asset-chain/12_XRWA.deploy.ts create mode 100644 contracts/deploy/testnet/asset-chain/12_XRWA.deploy.ts diff --git a/backend-all/package.json b/backend-all/package.json index fbe6ccf..d3fb05f 100644 --- a/backend-all/package.json +++ b/backend-all/package.json @@ -18,7 +18,9 @@ "contracts:sync": "SCRIPT=./src/gotbit-tools/scripts/shell/import-contracts.sh yarn script", "contracts:typings": "node ./src/gotbit-tools/scripts/typings.js", "\n# UTILS SCRIPTS:": "", - "script": "chmod +x $SCRIPT && $SCRIPT" + "script": "chmod +x $SCRIPT && $SCRIPT", + "dev-win": "yarn build-win && concurrently \"tsc -w\" \"cross-env DEBUG=true node-dev --respawn dist/app.js\"", + "build-win": "rimraf dist && tsc -p ." }, "jest": { "preset": "ts-jest", diff --git a/backend-all/src/gotbit-tools/node/rpc.ts b/backend-all/src/gotbit-tools/node/rpc.ts index 44404eb..24163e8 100644 --- a/backend-all/src/gotbit-tools/node/rpc.ts +++ b/backend-all/src/gotbit-tools/node/rpc.ts @@ -1,3 +1,4 @@ +import { arbitrum_mainnet_rpc, arbitrum_sepolia_rpc, base_mainnet_rpc, base_spolia_rpc, binance_mainnet_rpc, binance_testnet_rpc, ethereum_mainnet_rpc, ethereum_sepolia_rpc, polygon_amoy_rpc, polygon_mainnet_rpc } from '@/utils/env-var' import { ChainTag, RemoteChainTag, RpcFunction } from './utils/misc' import { extraRpcs } from './utils/node' @@ -61,26 +62,26 @@ export const universalRpc = (): RpcFunction => { return (chainTag: ChainTag) => { const a: Record = { avax_mainnet: ankr(chainTag), - bsc_mainnet: extraRpcs.bsc_mainnet[0], - arbitrum_mainnet: extraRpcs.arbitrum_mainnet[0], - eth_mainnet: extraRpcs.eth_mainnet[0], + bsc_mainnet: binance_mainnet_rpc, + arbitrum_mainnet: arbitrum_mainnet_rpc, + eth_mainnet: ethereum_mainnet_rpc, ftm_mainnet: ankr(chainTag), - polygon_mainnet: ankr(chainTag), + polygon_mainnet: polygon_mainnet_rpc, celo_mainnet: ankr(chainTag), - base_mainnet: ankr(chainTag), + base_mainnet: base_mainnet_rpc, bitlayer_mainnet: extraRpcs.bitlayer_mainnet[0], xend_mainnet: extraRpcs.xend_mainnet[0], avax_testnet: 'https://avalanche-fuji-c-chain.publicnode.com', - polygon_testnet: 'https://rpc-mumbai.maticvigil.com', + polygon_testnet: polygon_amoy_rpc, ftm_testnet: ankr(chainTag), rinkeby: ankr(chainTag), ropsten: ankr(chainTag), goerli: ankr(chainTag), - arbitrum_testnet: extraRpcs.arbitrum_testnet[0], + arbitrum_testnet: arbitrum_sepolia_rpc, // bsc_testnet: extraRpcs.bsc_testnet[0], - bsc_testnet: 'https://bsc-testnet.publicnode.com', + bsc_testnet: binance_testnet_rpc, localhost: extraRpcs.localhost[0], @@ -96,11 +97,11 @@ export const universalRpc = (): RpcFunction => { okex_testnet: extraRpcs.okex_testnet[0], cmp_testnet: extraRpcs.cmp_testnet[0], pulse_testnet: 'https://rpc.v4.testnet.pulsechain.com', - arbitrum_sepolia: extraRpcs.arbitrum_sepolia[0], + arbitrum_sepolia: arbitrum_sepolia_rpc, xend_testnet: extraRpcs.xend_testnet[0], - base_sepolia: extraRpcs.base_sepolia[0], - eth_sepolia: extraRpcs.eth_sepolia[0], - polygon_amoy: extraRpcs.polygon_amoy[0], + base_sepolia: base_spolia_rpc, + eth_sepolia: ethereum_sepolia_rpc, + polygon_amoy: polygon_amoy_rpc, bitlayer_testnet: extraRpcs.bitlayer_testnet[0], } as any return a[chainTag] diff --git a/backend-all/src/services/blockchain.ts b/backend-all/src/services/blockchain.ts index 4ee096e..ba81b15 100644 --- a/backend-all/src/services/blockchain.ts +++ b/backend-all/src/services/blockchain.ts @@ -106,6 +106,7 @@ export const signTransaction = async ( signatures = signatures.concat(res.data.signature) } } catch (error: any) { + console.log(error, 'dkdkdkdk') throw new Error(`relayer ${i + 1} error: ${error.message}`) } } diff --git a/backend-all/src/utils/env-var.ts b/backend-all/src/utils/env-var.ts new file mode 100644 index 0000000..88a74f9 --- /dev/null +++ b/backend-all/src/utils/env-var.ts @@ -0,0 +1,10 @@ +export const arbitrum_sepolia_rpc= process.env.ARBITRIUM_SEPOLIA_RPC +export const arbitrum_mainnet_rpc= process.env.ARBITRIUM_MAINNET_RPC +export const ethereum_sepolia_rpc= process.env.ETHEREUM_SEPOLIA_RPC +export const ethereum_mainnet_rpc= process.env.ETHEREUM_MAINNET_RPC +export const polygon_amoy_rpc= process.env.POLYGON_AMOY_RPC +export const polygon_mainnet_rpc= process.env.POLYGON_MAINNET_RPC +export const base_spolia_rpc= process.env.BASE_SEPOLIA_RPC +export const base_mainnet_rpc= process.env.BASE_MAINNET_RPC +export const binance_testnet_rpc= process.env.BINANCE_TESTNET_RPC +export const binance_mainnet_rpc= process.env.BINANCE_MAINNET_RPC \ No newline at end of file diff --git a/contracts/deploy/mainnet/asset-chain/12_XRWA.deploy.ts b/contracts/deploy/mainnet/asset-chain/12_XRWA.deploy.ts new file mode 100644 index 0000000..da8db37 --- /dev/null +++ b/contracts/deploy/mainnet/asset-chain/12_XRWA.deploy.ts @@ -0,0 +1,50 @@ +import { ethers, getNamedAccounts } from 'hardhat' +import type { DeployFunction } from 'hardhat-deploy/types' + +import type { BridgedAssetChainToken__factory } from '../../../typechain' +import { BigNumber } from 'ethers' +// import { wrapperHRE } from '../../../utils/helpers' +import { + BRIDGED_TOKEN_PARAMS, + CHAIN_IDS, + MAINNET_CHAIN_IDS, + MULTISIG_ADDRESSES, +} from '../../../config' +import { wrapperHRE } from '@/gotbit-tools/hardhat' + +const func: DeployFunction = async (hre) => { + const { deploy } = wrapperHRE(hre) + const [deployer] = await ethers.getSigners() + const { chainId } = await ethers.provider.getNetwork() + + if (chainId != CHAIN_IDS.assetChain) { + return + } + + const token = 'xRWA' + const params = BRIDGED_TOKEN_PARAMS[chainId]['USDT'] + const mulsigwallet = MULTISIG_ADDRESSES[MAINNET_CHAIN_IDS.assetChain] + if (!mulsigwallet) throw new Error('Multisig wallet not set') + + // const mulsigwallet = await ethers.getContract('MultiSigWallet') + + await deploy(token, { + contract: 'BridgedAssetChainToken', + from: deployer.address, + args: [ + 'Xend Finance RWA', + token, + 18, + 0, + params.isLockActive, + params.tokenOriginal, + params.chainIdOriginal, + mulsigwallet, + ], + log: true, + }) +} +export default func + +func.tags = ['xRWA.deploy'] +// func.dependencies = ['MultiSigWallet.deploy'] diff --git a/contracts/deploy/testnet/asset-chain/12_XRWA.deploy.ts b/contracts/deploy/testnet/asset-chain/12_XRWA.deploy.ts new file mode 100644 index 0000000..da8db37 --- /dev/null +++ b/contracts/deploy/testnet/asset-chain/12_XRWA.deploy.ts @@ -0,0 +1,50 @@ +import { ethers, getNamedAccounts } from 'hardhat' +import type { DeployFunction } from 'hardhat-deploy/types' + +import type { BridgedAssetChainToken__factory } from '../../../typechain' +import { BigNumber } from 'ethers' +// import { wrapperHRE } from '../../../utils/helpers' +import { + BRIDGED_TOKEN_PARAMS, + CHAIN_IDS, + MAINNET_CHAIN_IDS, + MULTISIG_ADDRESSES, +} from '../../../config' +import { wrapperHRE } from '@/gotbit-tools/hardhat' + +const func: DeployFunction = async (hre) => { + const { deploy } = wrapperHRE(hre) + const [deployer] = await ethers.getSigners() + const { chainId } = await ethers.provider.getNetwork() + + if (chainId != CHAIN_IDS.assetChain) { + return + } + + const token = 'xRWA' + const params = BRIDGED_TOKEN_PARAMS[chainId]['USDT'] + const mulsigwallet = MULTISIG_ADDRESSES[MAINNET_CHAIN_IDS.assetChain] + if (!mulsigwallet) throw new Error('Multisig wallet not set') + + // const mulsigwallet = await ethers.getContract('MultiSigWallet') + + await deploy(token, { + contract: 'BridgedAssetChainToken', + from: deployer.address, + args: [ + 'Xend Finance RWA', + token, + 18, + 0, + params.isLockActive, + params.tokenOriginal, + params.chainIdOriginal, + mulsigwallet, + ], + log: true, + }) +} +export default func + +func.tags = ['xRWA.deploy'] +// func.dependencies = ['MultiSigWallet.deploy'] From 20b21f030a6c49f74ec4152e8734cf6e1b781849 Mon Sep 17 00:00:00 2001 From: Stephen Udeh Date: Thu, 10 Jul 2025 18:04:32 +0100 Subject: [PATCH 02/19] worked on multiple rpc --- backend-all/src/utils/helpers.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/backend-all/src/utils/helpers.ts b/backend-all/src/utils/helpers.ts index 0827329..403442e 100644 --- a/backend-all/src/utils/helpers.ts +++ b/backend-all/src/utils/helpers.ts @@ -54,15 +54,15 @@ export async function getActiveRpc(rpcList: string[], timeoutMs: number = 5000) } // If JSON-RPC didn't work, try simple GET request - const getResponse = await fetch(rpc, { - signal: controller.signal, - }) + // const getResponse = await fetch(rpc, { + // signal: controller.signal, + // }) - if (getResponse.ok) { - clearTimeout(timeout) - console.log(`Choose index ${index} rpc`) - return rpc - } + // if (getResponse.ok) { + // clearTimeout(timeout) + // console.log(`Choose index ${index} rpc`) + // return rpc + // } } catch (error) { // Continue to next RPC if this one fails continue From 3084b210ad612037a2ac8921d876a2b1070abadf Mon Sep 17 00:00:00 2001 From: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> Date: Thu, 10 Jul 2025 19:59:46 +0100 Subject: [PATCH 03/19] Rpc (#82) * fix var issue (#80) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) Co-authored-by: Franklin Nwanze * Update blockchain.ts * Update blockchain.ts * fix bug (#78) (#79) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) * Update blockchain.ts * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * log to check error * changes to backend * added deploy script * added deploy script * add deploy script for xRWA * checking error * removed logs * [chores] use multiple rpc * worked on multiple rpc --------- Co-authored-by: Franklin --- backend-all/src/gotbit-tools/node/rpc.ts | 2 +- backend-all/src/services/blockchain.ts | 112 +++++++++-------- backend-all/src/utils/env-var.ts | 3 +- backend-all/src/utils/helpers.ts | 118 ++++++++++++++++++ backend-all/src/utils/useContracts.ts | 7 ++ .../asset-chain/01_BridgeCircle.deploy.ts | 1 + .../asset-chain/02_BridgeMint.deploy.ts | 1 + .../asset-chain/03_BridgeNative.deploy.ts | 1 + .../asset-chain/04_BridgeTransfer.deploy.ts | 1 + .../asset-chain/05_BridgeFactory.deploy.ts | 1 + .../mainnet/asset-chain/06_BTC.deploy.ts | 1 + .../mainnet/asset-chain/07_USDT.deploy.ts | 1 + .../mainnet/asset-chain/08_WNT.deploy.ts | 1 + .../mainnet/asset-chain/09_WBTC.deploy.ts | 1 + .../mainnet/asset-chain/12_XRWA.deploy.ts | 11 +- 15 files changed, 203 insertions(+), 59 deletions(-) create mode 100644 backend-all/src/utils/helpers.ts create mode 100644 backend-all/src/utils/useContracts.ts diff --git a/backend-all/src/gotbit-tools/node/rpc.ts b/backend-all/src/gotbit-tools/node/rpc.ts index 24163e8..f61a517 100644 --- a/backend-all/src/gotbit-tools/node/rpc.ts +++ b/backend-all/src/gotbit-tools/node/rpc.ts @@ -32,7 +32,7 @@ export const ankrRpc = (): RpcFunction => { if (chainTag === 'avax_testnet') return 'https://avalanche-fuji-c-chain.publicnode.com' - return 'https://rpc.ankr.com' + ankrPath[chainTag] ?? '' + return `https://rpc.ankr.com${ankrPath[chainTag]}` } } diff --git a/backend-all/src/services/blockchain.ts b/backend-all/src/services/blockchain.ts index ba81b15..0f9616e 100644 --- a/backend-all/src/services/blockchain.ts +++ b/backend-all/src/services/blockchain.ts @@ -10,6 +10,9 @@ import { eip712Transaction, } from '@/utils/constant' import axios from 'axios' +import { _getProvider } from '@/utils/helpers' +import { anyBridgeAssist } from '@/utils/useContracts' +import { relayerIndex } from '@/utils/env-var' export const getWalletEVM = () => new Wallet(process.env.PRIVATE_KEY!) @@ -61,60 +64,65 @@ export const signTransaction = async ( ) => { let tx: TransactionContract let relayers = 1 - if (fromChain.startsWith('evm.')) { - const { bridgeAssist } = useContracts(undefined, fromChain.slice(4) as ChainId) - tx = await bridgeAssist(fromBridgeAddress).transactions(fromUser, index) - relayers = +(await bridgeAssist(fromBridgeAddress).relayersLength()).toNumber() - const t = (await bridgeAssist(fromBridgeAddress).getRelayers()) - } else { - throw Error('bad arguments') - } - const provider = getProvider(fromChain.slice(4) as ChainId) - const currentBlock = await safeRead(provider.getBlockNumber(), 0) + if (!fromChain.startsWith('evm.')) throw Error(`Relayer ${relayerIndex} Bad arguments`) + const _fromChain = fromChain.slice(4) as ChainId + const _provider = await _getProvider(_fromChain) + const contract = anyBridgeAssist(fromBridgeAddress, _provider) + const transactionPromise = contract.transactions(fromUser, index) + const relayerLengthPromise = contract.relayersLength() + const res = await Promise.all([transactionPromise, relayerLengthPromise]) + tx = res[0] + if (!tx || tx.block.toNumber() === 0) throw Error('Transaction not found') + + relayers = +res[1].toNumber() + + // const provider = getProvider(fromChain.slice(4) as ChainId) + const currentBlock = await safeRead(_provider.getBlockNumber(), 0) if (currentBlock === 0 || tx.block.gt(currentBlock)) - throw Error('waiting for confirmations') - if (tx.toChain.startsWith('evm.')) { - const chainId = tx.toChain.replace('evm.', '') - // const { bridgeAssist } = useContracts(undefined, chainId as ChainId) - let signatures: any[] = [] - const allowedIps = process.env.ALLOWED_IPS?.split(',') - const clientIp = getClientIp(req) - if (process.env.IS_PUBLIC_RELAYER === 'false'){ - if (!allowedIps?.includes(clientIp)) { - throw new Error('IP not allowed to connect to the relayer') - } + throw Error(`Relayer ${relayerIndex} waiting for confirmations`) + if (!tx.toChain.startsWith('evm.')) throw Error(`Relayer ${relayerIndex} bad contract params`) + // if (tx.toChain.startsWith('evm.')) { + const chainId = tx.toChain.replace('evm.', '') + // const { bridgeAssist } = useContracts(undefined, chainId as ChainId) + let signatures: string[] = [] + const allowedIps = process.env.ALLOWED_IPS?.split(',') + const clientIp = getClientIp(req) + if (process.env.IS_PUBLIC_RELAYER === 'false') { + if (!allowedIps?.includes(clientIp)) { + throw new Error(`Relayer ${relayerIndex} IP not allowed to connect to the relayer`) } - const signer0 = await signHashedTransaction( - extractFulfillTransaction(tx), - chainId, - toBridgeAddress, - 0 - ) - signatures.push(signer0) - if (process.env.IS_PUBLIC_RELAYER === 'true' && relayers > 1) { - const relayersLength = relayers - 1 - const relayer1Url = process.env.RELAYER1_URL - const relayer2Url = process.env.RELAYER2_URL - for (let i = 1; i <= relayersLength; i++) { - try { - if (i === 1) { - const res = await axios.get(geturl(relayer1Url, req.query)) - signatures = signatures.concat(res.data.signature) - } - if (i === 2) { - const res = await axios.get(geturl(relayer2Url, req.query)) - signatures = signatures.concat(res.data.signature) - } - } catch (error: any) { - console.log(error, 'dkdkdkdk') - throw new Error(`relayer ${i + 1} error: ${error.message}`) + } + const signer0 = await signHashedTransaction( + extractFulfillTransaction(tx), + chainId, + toBridgeAddress, + 0 + ) + signatures.push(signer0) + if (process.env.IS_PUBLIC_RELAYER === 'true' && relayers > 1) { + const relayersLength = relayers - 1 + const relayer1Url = process.env.RELAYER1_URL + const relayer2Url = process.env.RELAYER2_URL + for (let i = 1; i <= relayersLength; i++) { + try { + if (i === 1) { + const res = await axios.get(geturl(relayer1Url, req.query)) + signatures = signatures.concat(res.data.signature) + } + if (i === 2) { + const res = await axios.get(geturl(relayer2Url, req.query)) + signatures = signatures.concat(res.data.signature) } + } catch (error: any) { + console.log(error, 'dkdkdkdk') + throw new Error(`relayer ${i + 1} error: ${error.message}`) } } - return signatures - } else { - throw Error('bad contract params') } + return signatures + // } else { + // throw Error('bad contract params') + // } } function geturl(baseUrl: string, searchParams: any) { @@ -128,15 +136,15 @@ function geturl(baseUrl: string, searchParams: any) { function getClientIp(req: any) { // Check Cloudflare headers first if (req.headers['cf-connecting-ip']) { - return req.headers['cf-connecting-ip']; + return req.headers['cf-connecting-ip'] } // Fallback to X-Forwarded-For (split and take the first IP) - const xForwardedFor = req.headers['x-forwarded-for']; + const xForwardedFor = req.headers['x-forwarded-for'] if (xForwardedFor) { - return xForwardedFor.split(',')[0].trim(); + return xForwardedFor.split(',')[0].trim() } // Default to direct connection IP - return req.connection.remoteAddress; + return req.connection.remoteAddress } diff --git a/backend-all/src/utils/env-var.ts b/backend-all/src/utils/env-var.ts index 88a74f9..9144a51 100644 --- a/backend-all/src/utils/env-var.ts +++ b/backend-all/src/utils/env-var.ts @@ -7,4 +7,5 @@ export const polygon_mainnet_rpc= process.env.POLYGON_MAINNET_RPC export const base_spolia_rpc= process.env.BASE_SEPOLIA_RPC export const base_mainnet_rpc= process.env.BASE_MAINNET_RPC export const binance_testnet_rpc= process.env.BINANCE_TESTNET_RPC -export const binance_mainnet_rpc= process.env.BINANCE_MAINNET_RPC \ No newline at end of file +export const binance_mainnet_rpc= process.env.BINANCE_MAINNET_RPC +export const relayerIndex= process.env.RELAYER_INDEX diff --git a/backend-all/src/utils/helpers.ts b/backend-all/src/utils/helpers.ts new file mode 100644 index 0000000..403442e --- /dev/null +++ b/backend-all/src/utils/helpers.ts @@ -0,0 +1,118 @@ +import { ChainId, ChainTag } from '@/gotbit-tools/node/types' +import { + arbitrum_mainnet_rpc, + arbitrum_sepolia_rpc, + base_mainnet_rpc, + base_spolia_rpc, + binance_mainnet_rpc, + binance_testnet_rpc, + ethereum_mainnet_rpc, + ethereum_sepolia_rpc, + polygon_amoy_rpc, + polygon_mainnet_rpc, + relayerIndex, +} from './env-var' +import { providers } from 'ethers' +import { universalRpc } from '@/gotbit-tools/node/rpc' +import { getChainName, getChainTag } from '@/gotbit-tools/node' + +export async function getActiveRpc(rpcList: string[], timeoutMs: number = 5000) { + /** + * Check a list of RPC endpoints and return the first active one. + * + * @param rpcList - Array of RPC URLs to check + * @param timeoutMs - Timeout in milliseconds for each request + * @returns The first active RPC URL found, or null if none are active + */ + + // Create AbortController for timeout functionality + const controller = new AbortController() + const timeout = setTimeout(() => controller.abort(), timeoutMs) + let index = 1 + for (const rpc of rpcList) { + try { + // First try Ethereum-style JSON-RPC call + const jsonRpcResponse = await fetch(rpc, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + jsonrpc: '2.0', + method: 'eth_blockNumber', + params: [], + id: 1, + }), + signal: controller.signal, + }) + + if (jsonRpcResponse.ok) { + const data = await jsonRpcResponse.json() + if (data.result) { + console.log(`Choose index ${index} rpc`) + clearTimeout(timeout) + return rpc + } + } + + // If JSON-RPC didn't work, try simple GET request + // const getResponse = await fetch(rpc, { + // signal: controller.signal, + // }) + + // if (getResponse.ok) { + // clearTimeout(timeout) + // console.log(`Choose index ${index} rpc`) + // return rpc + // } + } catch (error) { + // Continue to next RPC if this one fails + continue + } finally { + clearTimeout(timeout) + index++ + } + } + + return null +} + +export function getChainRPCS(chainId: ChainId) { + switch (chainId) { + case '42161': + return arbitrum_mainnet_rpc + case '421614': + return arbitrum_sepolia_rpc + case '8453': + return base_mainnet_rpc + case '84532': + return base_spolia_rpc + case '56': + return binance_mainnet_rpc + case '97': + return binance_testnet_rpc + case '1': + return ethereum_mainnet_rpc + default: + return undefined + } +} + +const _rpc = universalRpc() + +export async function _getProvider(chainId: ChainId) { + let rpc: string | null = '' + const rpcListString = getChainRPCS(chainId) + if (rpcListString) { + const rpcList = rpcListString.split(',') + rpc = await getActiveRpc(rpcList) + if (rpc) { + console.log(`Using RPC private RPC`) + } + } else { + rpc = _rpc(getChainTag(chainId)) + if (!rpc) throw new Error(`Relayer ${relayerIndex} Rpc error. Please try again later`) + rpc = await getActiveRpc([rpc]) + console.log(`Using RPC public RPC`) + } + if (!rpc) throw new Error(`Relayer ${relayerIndex} Rpc error. Please try again later`) + return new providers.JsonRpcProvider(rpc) +} diff --git a/backend-all/src/utils/useContracts.ts b/backend-all/src/utils/useContracts.ts new file mode 100644 index 0000000..d251cc8 --- /dev/null +++ b/backend-all/src/utils/useContracts.ts @@ -0,0 +1,7 @@ +import { providers } from "ethers"; +import { BridgeAssist__factory } from "@/contracts/typechain"; + +export function anyBridgeAssist(address: string, provider: providers.JsonRpcProvider){ + return BridgeAssist__factory.connect(address, provider) +} + diff --git a/contracts/deploy/mainnet/asset-chain/01_BridgeCircle.deploy.ts b/contracts/deploy/mainnet/asset-chain/01_BridgeCircle.deploy.ts index 02de321..bdc60dc 100644 --- a/contracts/deploy/mainnet/asset-chain/01_BridgeCircle.deploy.ts +++ b/contracts/deploy/mainnet/asset-chain/01_BridgeCircle.deploy.ts @@ -6,6 +6,7 @@ import { wrapperHRE } from '@/gotbit-tools/hardhat' import type { BridgeAssistCircleMintUpgradeable__factory } from '@/typechain' const func: DeployFunction = async (hre) => { + return const { deploy } = wrapperHRE(hre) const [deployer] = await ethers.getSigners() const { chainId } = await ethers.provider.getNetwork() diff --git a/contracts/deploy/mainnet/asset-chain/02_BridgeMint.deploy.ts b/contracts/deploy/mainnet/asset-chain/02_BridgeMint.deploy.ts index d2f4009..3bdfc1c 100644 --- a/contracts/deploy/mainnet/asset-chain/02_BridgeMint.deploy.ts +++ b/contracts/deploy/mainnet/asset-chain/02_BridgeMint.deploy.ts @@ -6,6 +6,7 @@ import { wrapperHRE } from '@/gotbit-tools/hardhat' import type { BridgeAssistMintUpgradeable__factory } from '@/typechain' const func: DeployFunction = async (hre) => { + return const { deploy } = wrapperHRE(hre) const [deployer] = await ethers.getSigners() const { chainId } = await ethers.provider.getNetwork() diff --git a/contracts/deploy/mainnet/asset-chain/03_BridgeNative.deploy.ts b/contracts/deploy/mainnet/asset-chain/03_BridgeNative.deploy.ts index 4c0e15b..5839ab5 100644 --- a/contracts/deploy/mainnet/asset-chain/03_BridgeNative.deploy.ts +++ b/contracts/deploy/mainnet/asset-chain/03_BridgeNative.deploy.ts @@ -6,6 +6,7 @@ import { wrapperHRE } from '@/gotbit-tools/hardhat' import type { BridgeAssistNativeUpgradeable__factory } from '@/typechain' const func: DeployFunction = async (hre) => { + return const { deploy } = wrapperHRE(hre) const [deployer] = await ethers.getSigners() const { chainId } = await ethers.provider.getNetwork() diff --git a/contracts/deploy/mainnet/asset-chain/04_BridgeTransfer.deploy.ts b/contracts/deploy/mainnet/asset-chain/04_BridgeTransfer.deploy.ts index 8621cb9..1952173 100644 --- a/contracts/deploy/mainnet/asset-chain/04_BridgeTransfer.deploy.ts +++ b/contracts/deploy/mainnet/asset-chain/04_BridgeTransfer.deploy.ts @@ -6,6 +6,7 @@ import { wrapperHRE } from '@/gotbit-tools/hardhat' import type { BridgeAssistTransferUpgradeable__factory } from '@/typechain' const func: DeployFunction = async (hre) => { + return const { deploy } = wrapperHRE(hre) const [deployer] = await ethers.getSigners() const { chainId } = await ethers.provider.getNetwork() diff --git a/contracts/deploy/mainnet/asset-chain/05_BridgeFactory.deploy.ts b/contracts/deploy/mainnet/asset-chain/05_BridgeFactory.deploy.ts index 1565b84..20db7bf 100644 --- a/contracts/deploy/mainnet/asset-chain/05_BridgeFactory.deploy.ts +++ b/contracts/deploy/mainnet/asset-chain/05_BridgeFactory.deploy.ts @@ -13,6 +13,7 @@ import type { } from '@/typechain' const func: DeployFunction = async (hre) => { + return const { deploy } = wrapperHRE(hre) const [deployer] = await ethers.getSigners() const { chainId } = await ethers.provider.getNetwork() diff --git a/contracts/deploy/mainnet/asset-chain/06_BTC.deploy.ts b/contracts/deploy/mainnet/asset-chain/06_BTC.deploy.ts index b287ced..c498e52 100644 --- a/contracts/deploy/mainnet/asset-chain/06_BTC.deploy.ts +++ b/contracts/deploy/mainnet/asset-chain/06_BTC.deploy.ts @@ -7,6 +7,7 @@ import type { BridgedAssetChainToken__factory, MultiSigWallet } from '@/typechai import { BigNumber } from 'ethers' const func: DeployFunction = async (hre) => { + return const { deploy } = wrapperHRE(hre) const [deployer] = await ethers.getSigners() const { chainId } = await ethers.provider.getNetwork() diff --git a/contracts/deploy/mainnet/asset-chain/07_USDT.deploy.ts b/contracts/deploy/mainnet/asset-chain/07_USDT.deploy.ts index 7da3a9c..b4fe91f 100644 --- a/contracts/deploy/mainnet/asset-chain/07_USDT.deploy.ts +++ b/contracts/deploy/mainnet/asset-chain/07_USDT.deploy.ts @@ -7,6 +7,7 @@ import type { BridgedAssetChainToken__factory, MultiSigWallet } from '@/typechai import { BigNumber } from 'ethers' const func: DeployFunction = async (hre) => { + return const { deploy } = wrapperHRE(hre) const [deployer] = await ethers.getSigners() const { chainId } = await ethers.provider.getNetwork() diff --git a/contracts/deploy/mainnet/asset-chain/08_WNT.deploy.ts b/contracts/deploy/mainnet/asset-chain/08_WNT.deploy.ts index c3ed8e4..789d691 100644 --- a/contracts/deploy/mainnet/asset-chain/08_WNT.deploy.ts +++ b/contracts/deploy/mainnet/asset-chain/08_WNT.deploy.ts @@ -7,6 +7,7 @@ import type { BridgedAssetChainToken__factory, MultiSigWallet } from '@/typechai import { BigNumber } from 'ethers' const func: DeployFunction = async (hre) => { + return const { deploy } = wrapperHRE(hre) const [deployer] = await ethers.getSigners() const { chainId } = await ethers.provider.getNetwork() diff --git a/contracts/deploy/mainnet/asset-chain/09_WBTC.deploy.ts b/contracts/deploy/mainnet/asset-chain/09_WBTC.deploy.ts index b4199e6..26497d6 100644 --- a/contracts/deploy/mainnet/asset-chain/09_WBTC.deploy.ts +++ b/contracts/deploy/mainnet/asset-chain/09_WBTC.deploy.ts @@ -13,6 +13,7 @@ import type { BridgedAssetChainToken__factory, MultiSigWallet } from '@/typechai import { BigNumber } from 'ethers' const func: DeployFunction = async (hre) => { + return const { deploy } = wrapperHRE(hre) const [deployer] = await ethers.getSigners() const { chainId } = await ethers.provider.getNetwork() diff --git a/contracts/deploy/mainnet/asset-chain/12_XRWA.deploy.ts b/contracts/deploy/mainnet/asset-chain/12_XRWA.deploy.ts index da8db37..78ba4ed 100644 --- a/contracts/deploy/mainnet/asset-chain/12_XRWA.deploy.ts +++ b/contracts/deploy/mainnet/asset-chain/12_XRWA.deploy.ts @@ -17,12 +17,13 @@ const func: DeployFunction = async (hre) => { const [deployer] = await ethers.getSigners() const { chainId } = await ethers.provider.getNetwork() - if (chainId != CHAIN_IDS.assetChain) { + if (chainId != MAINNET_CHAIN_IDS.assetChain) { return } const token = 'xRWA' - const params = BRIDGED_TOKEN_PARAMS[chainId]['USDT'] + // const params = BRIDGED_TOKEN_PARAMS[chainId]['USDT'] + const mulsigwallet = MULTISIG_ADDRESSES[MAINNET_CHAIN_IDS.assetChain] if (!mulsigwallet) throw new Error('Multisig wallet not set') @@ -36,9 +37,9 @@ const func: DeployFunction = async (hre) => { token, 18, 0, - params.isLockActive, - params.tokenOriginal, - params.chainIdOriginal, + false, + '0x3096e7BFd0878Cc65be71f8899Bc4CFB57187Ba3', + MAINNET_CHAIN_IDS.arbitrum, mulsigwallet, ], log: true, From 2991bb7a6745efc4151049faa22dc8e734908a63 Mon Sep 17 00:00:00 2001 From: Stephen Udeh Date: Tue, 5 Aug 2025 13:56:46 +0100 Subject: [PATCH 04/19] polygon support --- backend-all/src/contracts/contracts.json | 9146 ++++++++++++++++++++++ backend-all/src/gotbit.config.ts | 5 +- contracts/config.ts | 3 +- contracts/hardhat.config.ts | 6 + contracts/package.json | 1 + 5 files changed, 9158 insertions(+), 3 deletions(-) diff --git a/backend-all/src/contracts/contracts.json b/backend-all/src/contracts/contracts.json index ba6f05e..ea7a495 100644 --- a/backend-all/src/contracts/contracts.json +++ b/backend-all/src/contracts/contracts.json @@ -65917,6 +65917,9152 @@ } } } + ], + "137": [ + { + "name": "polygon", + "chainId": "137", + "contracts": { + "BridgeAssistCircleMintUpgradeable": { + "address": "0xAACc0745776A3F5dB8B1b86C46e553A08Ab1e9b2", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "BridgeAssist": { + "address": "0x68eeDDBb8401349aFe6B47E56d64427880cb0cF9", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "Token": { + "address": "0x3095A7217Cda6EEc1E6BEdACb56974431f2B3623", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_decimals", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "_totalSupply", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "BridgeAssistMintUpgradeable": { + "address": "0xD24dBcb11Ee49cc4C3e52EEcda9134971bb3efA1", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "BridgeAssistNativeUpgradeable": { + "address": "0x11C985F8319b377Ae39944357DC332CEcD06Ae0e", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeFulfillSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "BridgeAssistTransferUpgradeable": { + "address": "0xAfbe0d45f7760c906169987B88Ee83a53EF98B4B", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "DefaultProxyAdmin": { + "address": "0xc3dD6D664452b19A40fa6212c5A9A242c9feCeb1", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "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": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "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": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ] + }, + "BridgeFactoryUpgradeable_Implementation": { + "address": "0x6A3fA04729387bD65cf0ed6527764c1aeD3CF5DE", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ArrayLengthExceedsLimit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeDuplicate", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "BridgeTypeInvalidImplementation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateImplementations", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidIndex", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidOffsetLimit", + "type": "error" + }, + { + "inputs": [], + "name": "NoBridgesByToken", + "type": "error" + }, + { + "inputs": [], + "name": "NotMultiSigWallet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "TokenZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroLengthArray", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "bridgeTransfer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeMint", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeNative", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeCircle", + "type": "address" + } + ], + "name": "BridgeAssistImplementationsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "ADD_REMOVE_LIMIT_PER_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CREATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTISIG_WALLET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "bridges", + "type": "address[]" + } + ], + "name": "addBridgeAssists", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BridgeFactoryUpgradeable.BridgeType", + "name": "", + "type": "uint8" + } + ], + "name": "bridgeAssistImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeAssistTransferImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistMintImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistNativeImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistCircleMintBurnImplementation_", + "type": "address" + } + ], + "name": "changeBridgeAssistImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BridgeFactoryUpgradeable.BridgeType", + "name": "bridgeType", + "type": "uint8" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold", + "type": "uint256" + } + ], + "name": "createBridgeAssist", + "outputs": [ + { + "internalType": "address", + "name": "bridge", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getBridgeByToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "getBridgesByToken", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getBridgesByTokenLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getCreatedBridgeInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct BridgeFactoryUpgradeable.BridgeAssistInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "getCreatedBridgesInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct BridgeFactoryUpgradeable.BridgeAssistInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCreatedBridgesLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeAssistTransferImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistMintImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistNativeImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistCircleMintBurnImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "multisigWalletAddress_", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "bridges", + "type": "address[]" + } + ], + "name": "removeBridgeAssists", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "BridgeFactoryUpgradeable_Proxy": { + "address": "0xa8D522f81f545EA82a06cFe6A6810b8dF2b0690F", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "initialLogic", + "type": "address" + }, + { + "internalType": "address", + "name": "initialAdmin", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "BridgeFactoryUpgradeable": { + "address": "0xEd0534911CA0976dEe191eb0D6051105D5BC4AD2", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "ArrayLengthExceedsLimit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeDuplicate", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "BridgeTypeInvalidImplementation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateImplementations", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidIndex", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidOffsetLimit", + "type": "error" + }, + { + "inputs": [], + "name": "NoBridgesByToken", + "type": "error" + }, + { + "inputs": [], + "name": "NotMultiSigWallet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "TokenZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroLengthArray", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "bridgeTransfer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeMint", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeNative", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeCircle", + "type": "address" + } + ], + "name": "BridgeAssistImplementationsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "ADD_REMOVE_LIMIT_PER_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CREATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTISIG_WALLET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "bridges", + "type": "address[]" + } + ], + "name": "addBridgeAssists", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BridgeFactoryUpgradeable.BridgeType", + "name": "", + "type": "uint8" + } + ], + "name": "bridgeAssistImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeAssistTransferImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistMintImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistNativeImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistCircleMintBurnImplementation_", + "type": "address" + } + ], + "name": "changeBridgeAssistImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BridgeFactoryUpgradeable.BridgeType", + "name": "bridgeType", + "type": "uint8" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold", + "type": "uint256" + } + ], + "name": "createBridgeAssist", + "outputs": [ + { + "internalType": "address", + "name": "bridge", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getBridgeByToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "getBridgesByToken", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getBridgesByTokenLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getCreatedBridgeInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct BridgeFactoryUpgradeable.BridgeAssistInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "getCreatedBridgesInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct BridgeFactoryUpgradeable.BridgeAssistInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCreatedBridgesLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeAssistTransferImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistMintImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistNativeImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistCircleMintBurnImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "multisigWalletAddress_", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "bridges", + "type": "address[]" + } + ], + "name": "removeBridgeAssists", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "initialLogic", + "type": "address" + }, + { + "internalType": "address", + "name": "initialAdmin", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "USDT": { + "address": "0x939768A338621CfDa43A5a59ED61F85b0BcDDbf2", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "totalSupply_", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isLockActive_", + "type": "bool" + }, + { + "internalType": "address", + "name": "tokenOriginal_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "chainIdOriginal_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "multisigWalletAddress_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "BlacklistStageDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isBlacklisted", + "type": "bool" + } + ], + "name": "BlacklistedStatusUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "BURNER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CHAIN_ID_ORIGINAL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTISIG_WALLET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_ORIGINAL", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "disableLockStage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isBlacklisted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isLockActive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "bool", + "name": "status", + "type": "bool" + } + ], + "name": "setBlacklisted", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] + } + } + } ] } diff --git a/backend-all/src/gotbit.config.ts b/backend-all/src/gotbit.config.ts index fbd56f0..d616745 100644 --- a/backend-all/src/gotbit.config.ts +++ b/backend-all/src/gotbit.config.ts @@ -4,7 +4,7 @@ import { universalRpc } from '@/gotbit-tools/node/rpc' export const IS_PROD = process.env.PROD === 'true' export const config = defineConfig({ - chainIds: ['97', '42421', '421614', '200810', '200901', '42420', '42161', '56', '8453', '84532', "1"], + chainIds: ['97', '42421', '421614', '200810', '200901', '42420', '42161', '56', '8453', '84532', "1", '137'], // DEFAULT_CHAINID: IS_PROD ? '56' : '97', DEFAULT_CHAINID: '97', rpc: universalRpc(), @@ -26,5 +26,6 @@ export const contracts = defineContracts({ '56': {}, '8453': {}, '84532': {}, - "1": {} + "1": {}, + "137": {} }) diff --git a/contracts/config.ts b/contracts/config.ts index 0b1f7d6..9f15867 100644 --- a/contracts/config.ts +++ b/contracts/config.ts @@ -316,5 +316,6 @@ export const MULTISIG_ADDRESSES = { [MAINNET_CHAIN_IDS.base]: '', [MAINNET_CHAIN_IDS.bitlayer]: '', [MAINNET_CHAIN_IDS.bsc]: '', - [MAINNET_CHAIN_IDS.ethereum]: '' + [MAINNET_CHAIN_IDS.ethereum]: '', + [MAINNET_CHAIN_IDS.polygon]: '' } \ No newline at end of file diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index 53f6384..65033ab 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -103,6 +103,12 @@ const config: HardhatUserConfig = { tags: ['mainnet'], deploy: ['deploy/mainnet/non-asset-chain'], accounts: [process.env.PRIVATE_TEST!, process.env.PRIVATE_TEST2!], + }, + polygon: { + url: 'https://polygon-rpc.com', + tags: ['mainnet'], + deploy: ['deploy/mainnet/non-asset-chain'], + accounts: [process.env.PRIVATE_TEST!, process.env.PRIVATE_TEST2!], } }, gasReporter: { diff --git a/contracts/package.json b/contracts/package.json index 327fe85..f5491a9 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -36,6 +36,7 @@ "deploy:xend": "hardhat deploy --export-all main/contracts.json --network xend", "deploy:bsc": "hardhat deploy --export-all main/contracts.json --network bsc", "deploy:ethereum": "hardhat deploy --export-all main/contracts.json --network ethereum", + "deploy:polygon": "hardhat deploy --export-all main/contracts.json --network polygon", "factory:arb_main": "hardhat --network arbitrum run scripts/factory.ts", "factory:xend_main": "hardhat --network xend run scripts/factory.ts", "factory:bsc_main": "hardhat --network bsc run scripts/factory.ts", From 7b64fb3e58fcd4cfa36d69837966a7c800b67bed Mon Sep 17 00:00:00 2001 From: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> Date: Wed, 6 Aug 2025 08:05:49 +0100 Subject: [PATCH 05/19] polygon support (#84) --- backend-all/src/contracts/contracts.json | 9146 ++++++++++++++++++++++ backend-all/src/gotbit.config.ts | 5 +- contracts/config.ts | 3 +- contracts/hardhat.config.ts | 6 + contracts/package.json | 1 + 5 files changed, 9158 insertions(+), 3 deletions(-) diff --git a/backend-all/src/contracts/contracts.json b/backend-all/src/contracts/contracts.json index ba6f05e..ea7a495 100644 --- a/backend-all/src/contracts/contracts.json +++ b/backend-all/src/contracts/contracts.json @@ -65917,6 +65917,9152 @@ } } } + ], + "137": [ + { + "name": "polygon", + "chainId": "137", + "contracts": { + "BridgeAssistCircleMintUpgradeable": { + "address": "0xAACc0745776A3F5dB8B1b86C46e553A08Ab1e9b2", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "BridgeAssist": { + "address": "0x68eeDDBb8401349aFe6B47E56d64427880cb0cF9", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "Token": { + "address": "0x3095A7217Cda6EEc1E6BEdACb56974431f2B3623", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_decimals", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "_totalSupply", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "BridgeAssistMintUpgradeable": { + "address": "0xD24dBcb11Ee49cc4C3e52EEcda9134971bb3efA1", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "BridgeAssistNativeUpgradeable": { + "address": "0x11C985F8319b377Ae39944357DC332CEcD06Ae0e", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeFulfillSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "BridgeAssistTransferUpgradeable": { + "address": "0xAfbe0d45f7760c906169987B88Ee83a53EF98B4B", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "DefaultProxyAdmin": { + "address": "0xc3dD6D664452b19A40fa6212c5A9A242c9feCeb1", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "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": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "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": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ] + }, + "BridgeFactoryUpgradeable_Implementation": { + "address": "0x6A3fA04729387bD65cf0ed6527764c1aeD3CF5DE", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ArrayLengthExceedsLimit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeDuplicate", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "BridgeTypeInvalidImplementation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateImplementations", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidIndex", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidOffsetLimit", + "type": "error" + }, + { + "inputs": [], + "name": "NoBridgesByToken", + "type": "error" + }, + { + "inputs": [], + "name": "NotMultiSigWallet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "TokenZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroLengthArray", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "bridgeTransfer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeMint", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeNative", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeCircle", + "type": "address" + } + ], + "name": "BridgeAssistImplementationsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "ADD_REMOVE_LIMIT_PER_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CREATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTISIG_WALLET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "bridges", + "type": "address[]" + } + ], + "name": "addBridgeAssists", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BridgeFactoryUpgradeable.BridgeType", + "name": "", + "type": "uint8" + } + ], + "name": "bridgeAssistImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeAssistTransferImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistMintImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistNativeImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistCircleMintBurnImplementation_", + "type": "address" + } + ], + "name": "changeBridgeAssistImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BridgeFactoryUpgradeable.BridgeType", + "name": "bridgeType", + "type": "uint8" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold", + "type": "uint256" + } + ], + "name": "createBridgeAssist", + "outputs": [ + { + "internalType": "address", + "name": "bridge", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getBridgeByToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "getBridgesByToken", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getBridgesByTokenLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getCreatedBridgeInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct BridgeFactoryUpgradeable.BridgeAssistInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "getCreatedBridgesInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct BridgeFactoryUpgradeable.BridgeAssistInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCreatedBridgesLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeAssistTransferImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistMintImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistNativeImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistCircleMintBurnImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "multisigWalletAddress_", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "bridges", + "type": "address[]" + } + ], + "name": "removeBridgeAssists", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "BridgeFactoryUpgradeable_Proxy": { + "address": "0xa8D522f81f545EA82a06cFe6A6810b8dF2b0690F", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "initialLogic", + "type": "address" + }, + { + "internalType": "address", + "name": "initialAdmin", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "BridgeFactoryUpgradeable": { + "address": "0xEd0534911CA0976dEe191eb0D6051105D5BC4AD2", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "ArrayLengthExceedsLimit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeDuplicate", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "BridgeTypeInvalidImplementation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateImplementations", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidIndex", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidOffsetLimit", + "type": "error" + }, + { + "inputs": [], + "name": "NoBridgesByToken", + "type": "error" + }, + { + "inputs": [], + "name": "NotMultiSigWallet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "TokenZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroLengthArray", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "bridgeTransfer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeMint", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeNative", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeCircle", + "type": "address" + } + ], + "name": "BridgeAssistImplementationsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "ADD_REMOVE_LIMIT_PER_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CREATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTISIG_WALLET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "bridges", + "type": "address[]" + } + ], + "name": "addBridgeAssists", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BridgeFactoryUpgradeable.BridgeType", + "name": "", + "type": "uint8" + } + ], + "name": "bridgeAssistImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeAssistTransferImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistMintImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistNativeImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistCircleMintBurnImplementation_", + "type": "address" + } + ], + "name": "changeBridgeAssistImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BridgeFactoryUpgradeable.BridgeType", + "name": "bridgeType", + "type": "uint8" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold", + "type": "uint256" + } + ], + "name": "createBridgeAssist", + "outputs": [ + { + "internalType": "address", + "name": "bridge", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getBridgeByToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "getBridgesByToken", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getBridgesByTokenLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getCreatedBridgeInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct BridgeFactoryUpgradeable.BridgeAssistInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "getCreatedBridgesInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct BridgeFactoryUpgradeable.BridgeAssistInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCreatedBridgesLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeAssistTransferImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistMintImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistNativeImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistCircleMintBurnImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "multisigWalletAddress_", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "bridges", + "type": "address[]" + } + ], + "name": "removeBridgeAssists", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "initialLogic", + "type": "address" + }, + { + "internalType": "address", + "name": "initialAdmin", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "USDT": { + "address": "0x939768A338621CfDa43A5a59ED61F85b0BcDDbf2", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "totalSupply_", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isLockActive_", + "type": "bool" + }, + { + "internalType": "address", + "name": "tokenOriginal_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "chainIdOriginal_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "multisigWalletAddress_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "BlacklistStageDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isBlacklisted", + "type": "bool" + } + ], + "name": "BlacklistedStatusUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "BURNER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CHAIN_ID_ORIGINAL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTISIG_WALLET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_ORIGINAL", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "disableLockStage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isBlacklisted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isLockActive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "bool", + "name": "status", + "type": "bool" + } + ], + "name": "setBlacklisted", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] + } + } + } ] } diff --git a/backend-all/src/gotbit.config.ts b/backend-all/src/gotbit.config.ts index fbd56f0..d616745 100644 --- a/backend-all/src/gotbit.config.ts +++ b/backend-all/src/gotbit.config.ts @@ -4,7 +4,7 @@ import { universalRpc } from '@/gotbit-tools/node/rpc' export const IS_PROD = process.env.PROD === 'true' export const config = defineConfig({ - chainIds: ['97', '42421', '421614', '200810', '200901', '42420', '42161', '56', '8453', '84532', "1"], + chainIds: ['97', '42421', '421614', '200810', '200901', '42420', '42161', '56', '8453', '84532', "1", '137'], // DEFAULT_CHAINID: IS_PROD ? '56' : '97', DEFAULT_CHAINID: '97', rpc: universalRpc(), @@ -26,5 +26,6 @@ export const contracts = defineContracts({ '56': {}, '8453': {}, '84532': {}, - "1": {} + "1": {}, + "137": {} }) diff --git a/contracts/config.ts b/contracts/config.ts index 0b1f7d6..9f15867 100644 --- a/contracts/config.ts +++ b/contracts/config.ts @@ -316,5 +316,6 @@ export const MULTISIG_ADDRESSES = { [MAINNET_CHAIN_IDS.base]: '', [MAINNET_CHAIN_IDS.bitlayer]: '', [MAINNET_CHAIN_IDS.bsc]: '', - [MAINNET_CHAIN_IDS.ethereum]: '' + [MAINNET_CHAIN_IDS.ethereum]: '', + [MAINNET_CHAIN_IDS.polygon]: '' } \ No newline at end of file diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index 53f6384..65033ab 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -103,6 +103,12 @@ const config: HardhatUserConfig = { tags: ['mainnet'], deploy: ['deploy/mainnet/non-asset-chain'], accounts: [process.env.PRIVATE_TEST!, process.env.PRIVATE_TEST2!], + }, + polygon: { + url: 'https://polygon-rpc.com', + tags: ['mainnet'], + deploy: ['deploy/mainnet/non-asset-chain'], + accounts: [process.env.PRIVATE_TEST!, process.env.PRIVATE_TEST2!], } }, gasReporter: { diff --git a/contracts/package.json b/contracts/package.json index 327fe85..f5491a9 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -36,6 +36,7 @@ "deploy:xend": "hardhat deploy --export-all main/contracts.json --network xend", "deploy:bsc": "hardhat deploy --export-all main/contracts.json --network bsc", "deploy:ethereum": "hardhat deploy --export-all main/contracts.json --network ethereum", + "deploy:polygon": "hardhat deploy --export-all main/contracts.json --network polygon", "factory:arb_main": "hardhat --network arbitrum run scripts/factory.ts", "factory:xend_main": "hardhat --network xend run scripts/factory.ts", "factory:bsc_main": "hardhat --network bsc run scripts/factory.ts", From ee25c6c9fc92b064b31b4ca821c95ac816f56ed3 Mon Sep 17 00:00:00 2001 From: Stephen Udeh Date: Fri, 8 Aug 2025 14:41:08 +0100 Subject: [PATCH 06/19] use polygon rpc from env --- backend-all/src/contracts/contracts.json | 9146 ++++++++++++++++++++++ backend-all/src/gotbit.config.ts | 5 +- backend-all/src/utils/helpers.ts | 4 + 3 files changed, 9153 insertions(+), 2 deletions(-) diff --git a/backend-all/src/contracts/contracts.json b/backend-all/src/contracts/contracts.json index ea7a495..1a14fdd 100644 --- a/backend-all/src/contracts/contracts.json +++ b/backend-all/src/contracts/contracts.json @@ -75063,6 +75063,9152 @@ } } } + ], + "80002": [ + { + "name": "polygon testnet", + "chainId": "80002", + "contracts": { + "BridgeAssistCircleMintUpgradeable": { + "address": "0xAACc0745776A3F5dB8B1b86C46e553A08Ab1e9b2", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "BridgeAssist": { + "address": "0x68eeDDBb8401349aFe6B47E56d64427880cb0cF9", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "Token": { + "address": "0x3095A7217Cda6EEc1E6BEdACb56974431f2B3623", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_decimals", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "_totalSupply", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "BridgeAssistMintUpgradeable": { + "address": "0xD24dBcb11Ee49cc4C3e52EEcda9134971bb3efA1", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "BridgeAssistNativeUpgradeable": { + "address": "0x11C985F8319b377Ae39944357DC332CEcD06Ae0e", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeFulfillSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "BridgeAssistTransferUpgradeable": { + "address": "0xAfbe0d45f7760c906169987B88Ee83a53EF98B4B", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "ChainAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "ChainRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + } + ], + "name": "FeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeWallet", + "type": "address" + } + ], + "name": "FeeWalletSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "FulfilledTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + } + ], + "name": "LimitPerSendSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "RelayerConsensusThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "RelayerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "name": "SentTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CURRENT_CHAIN_B32", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FULFILL_TX_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_RELAYERS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "exchangeRatesFromPow", + "type": "uint256[]" + } + ], + "name": "addChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeRateFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeFulfill", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "fromUser", + "type": "string" + }, + { + "internalType": "address", + "name": "toUser", + "type": "address" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.FulfillTx", + "name": "transaction", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "fulfill", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "fulfilledAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactions", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserTransactionsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit_", + "type": "uint256" + } + ], + "name": "getUserTransactionsSlice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "internalType": "struct BridgeAssistGenericUpgradeable.Transaction[]", + "name": "transactions_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chain", + "type": "string" + } + ], + "name": "isSupportedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerSend", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerConsensusThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "relayers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayersLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "chains", + "type": "string[]" + } + ], + "name": "removeChains", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "feeSend_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeWallet_", + "type": "address" + } + ], + "name": "setFeeWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerSend_", + "type": "uint256" + } + ], + "name": "setLimitPerSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "relayers_", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold_", + "type": "uint256" + } + ], + "name": "setRelayers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supportedChainList", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transactions", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fromUser", + "type": "address" + }, + { + "internalType": "string", + "name": "toUser", + "type": "string" + }, + { + "internalType": "string", + "name": "fromChain", + "type": "string" + }, + { + "internalType": "string", + "name": "toChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "DefaultProxyAdmin": { + "address": "0xc3dD6D664452b19A40fa6212c5A9A242c9feCeb1", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "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": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "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": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ] + }, + "BridgeFactoryUpgradeable_Implementation": { + "address": "0x6A3fA04729387bD65cf0ed6527764c1aeD3CF5DE", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ArrayLengthExceedsLimit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeDuplicate", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "BridgeTypeInvalidImplementation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateImplementations", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidIndex", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidOffsetLimit", + "type": "error" + }, + { + "inputs": [], + "name": "NoBridgesByToken", + "type": "error" + }, + { + "inputs": [], + "name": "NotMultiSigWallet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "TokenZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroLengthArray", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "bridgeTransfer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeMint", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeNative", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeCircle", + "type": "address" + } + ], + "name": "BridgeAssistImplementationsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "ADD_REMOVE_LIMIT_PER_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CREATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTISIG_WALLET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "bridges", + "type": "address[]" + } + ], + "name": "addBridgeAssists", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BridgeFactoryUpgradeable.BridgeType", + "name": "", + "type": "uint8" + } + ], + "name": "bridgeAssistImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeAssistTransferImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistMintImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistNativeImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistCircleMintBurnImplementation_", + "type": "address" + } + ], + "name": "changeBridgeAssistImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BridgeFactoryUpgradeable.BridgeType", + "name": "bridgeType", + "type": "uint8" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold", + "type": "uint256" + } + ], + "name": "createBridgeAssist", + "outputs": [ + { + "internalType": "address", + "name": "bridge", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getBridgeByToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "getBridgesByToken", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getBridgesByTokenLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getCreatedBridgeInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct BridgeFactoryUpgradeable.BridgeAssistInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "getCreatedBridgesInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct BridgeFactoryUpgradeable.BridgeAssistInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCreatedBridgesLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeAssistTransferImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistMintImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistNativeImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistCircleMintBurnImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "multisigWalletAddress_", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "bridges", + "type": "address[]" + } + ], + "name": "removeBridgeAssists", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "BridgeFactoryUpgradeable_Proxy": { + "address": "0xa8D522f81f545EA82a06cFe6A6810b8dF2b0690F", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "initialLogic", + "type": "address" + }, + { + "internalType": "address", + "name": "initialAdmin", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "BridgeFactoryUpgradeable": { + "address": "0xEd0534911CA0976dEe191eb0D6051105D5BC4AD2", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "ArrayLengthExceedsLimit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeDuplicate", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "BridgeTypeInvalidImplementation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "BridgeZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateImplementations", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidIndex", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidOffsetLimit", + "type": "error" + }, + { + "inputs": [], + "name": "NoBridgesByToken", + "type": "error" + }, + { + "inputs": [], + "name": "NotMultiSigWallet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "TokenZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroLengthArray", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "bridgeTransfer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeMint", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeNative", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bridgeCircle", + "type": "address" + } + ], + "name": "BridgeAssistImplementationsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "BridgeAssistRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "ADD_REMOVE_LIMIT_PER_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CREATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTISIG_WALLET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "bridges", + "type": "address[]" + } + ], + "name": "addBridgeAssists", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BridgeFactoryUpgradeable.BridgeType", + "name": "", + "type": "uint8" + } + ], + "name": "bridgeAssistImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeAssistTransferImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistMintImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistNativeImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistCircleMintBurnImplementation_", + "type": "address" + } + ], + "name": "changeBridgeAssistImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BridgeFactoryUpgradeable.BridgeType", + "name": "bridgeType", + "type": "uint8" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limitPerSend", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeWallet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeSend", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeFulfill", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address[]", + "name": "relayers", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "relayerConsensusThreshold", + "type": "uint256" + } + ], + "name": "createBridgeAssist", + "outputs": [ + { + "internalType": "address", + "name": "bridge", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getBridgeByToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "getBridgesByToken", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getBridgesByTokenLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getCreatedBridgeInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct BridgeFactoryUpgradeable.BridgeAssistInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "getCreatedBridgesInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "bridgeAssist", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct BridgeFactoryUpgradeable.BridgeAssistInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCreatedBridgesLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeAssistTransferImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistMintImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistNativeImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "bridgeAssistCircleMintBurnImplementation_", + "type": "address" + }, + { + "internalType": "address", + "name": "multisigWalletAddress_", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "bridges", + "type": "address[]" + } + ], + "name": "removeBridgeAssists", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "initialLogic", + "type": "address" + }, + { + "internalType": "address", + "name": "initialAdmin", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "USDT": { + "address": "0x939768A338621CfDa43A5a59ED61F85b0BcDDbf2", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "totalSupply_", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isLockActive_", + "type": "bool" + }, + { + "internalType": "address", + "name": "tokenOriginal_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "chainIdOriginal_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "multisigWalletAddress_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "BlacklistStageDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isBlacklisted", + "type": "bool" + } + ], + "name": "BlacklistedStatusUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "BURNER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CHAIN_ID_ORIGINAL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTISIG_WALLET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_ORIGINAL", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "disableLockStage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isBlacklisted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isLockActive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "bool", + "name": "status", + "type": "bool" + } + ], + "name": "setBlacklisted", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] + } + } + } ] } diff --git a/backend-all/src/gotbit.config.ts b/backend-all/src/gotbit.config.ts index d616745..9d32e2c 100644 --- a/backend-all/src/gotbit.config.ts +++ b/backend-all/src/gotbit.config.ts @@ -4,7 +4,7 @@ import { universalRpc } from '@/gotbit-tools/node/rpc' export const IS_PROD = process.env.PROD === 'true' export const config = defineConfig({ - chainIds: ['97', '42421', '421614', '200810', '200901', '42420', '42161', '56', '8453', '84532', "1", '137'], + chainIds: ['97', '42421', '421614', '200810', '200901', '42420', '42161', '56', '8453', '84532', "1", '137', '80002'], // DEFAULT_CHAINID: IS_PROD ? '56' : '97', DEFAULT_CHAINID: '97', rpc: universalRpc(), @@ -27,5 +27,6 @@ export const contracts = defineContracts({ '8453': {}, '84532': {}, "1": {}, - "137": {} + "137": {}, + "80002": {} }) diff --git a/backend-all/src/utils/helpers.ts b/backend-all/src/utils/helpers.ts index 403442e..a496f7c 100644 --- a/backend-all/src/utils/helpers.ts +++ b/backend-all/src/utils/helpers.ts @@ -91,6 +91,10 @@ export function getChainRPCS(chainId: ChainId) { return binance_testnet_rpc case '1': return ethereum_mainnet_rpc + case '137': + return polygon_mainnet_rpc + case '80002': + return polygon_amoy_rpc default: return undefined } From 5f3fdb466cd005ba30a00d9951558f944b47968f Mon Sep 17 00:00:00 2001 From: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> Date: Wed, 20 Aug 2025 20:05:41 +0100 Subject: [PATCH 07/19] finish wnt-restriction on arb (#88) --- backend-all/src/gotbit-tools/node/rpc.ts | 8 +- .../src/gotbit-tools/node/utils/node.ts | 2 +- backend-all/src/services/blockchain.ts | 76 ++++++- backend-all/src/utils/constant.ts | 196 ++++++++++++++++++ backend-all/src/utils/helpers.ts | 1 + backend-all/src/utils/useContracts.ts | 6 +- 6 files changed, 281 insertions(+), 8 deletions(-) diff --git a/backend-all/src/gotbit-tools/node/rpc.ts b/backend-all/src/gotbit-tools/node/rpc.ts index f61a517..c4d6fea 100644 --- a/backend-all/src/gotbit-tools/node/rpc.ts +++ b/backend-all/src/gotbit-tools/node/rpc.ts @@ -97,11 +97,11 @@ export const universalRpc = (): RpcFunction => { okex_testnet: extraRpcs.okex_testnet[0], cmp_testnet: extraRpcs.cmp_testnet[0], pulse_testnet: 'https://rpc.v4.testnet.pulsechain.com', - arbitrum_sepolia: arbitrum_sepolia_rpc, + arbitrum_sepolia: extraRpcs.arbitrum_sepolia[0], xend_testnet: extraRpcs.xend_testnet[0], - base_sepolia: base_spolia_rpc, - eth_sepolia: ethereum_sepolia_rpc, - polygon_amoy: polygon_amoy_rpc, + base_sepolia: extraRpcs.base_sepolia[0], + eth_sepolia: extraRpcs.eth_sepolia[0], + polygon_amoy: extraRpcs.polygon_amoy[0], bitlayer_testnet: extraRpcs.bitlayer_testnet[0], } as any return a[chainTag] diff --git a/backend-all/src/gotbit-tools/node/utils/node.ts b/backend-all/src/gotbit-tools/node/utils/node.ts index fb18f39..7698cc5 100644 --- a/backend-all/src/gotbit-tools/node/utils/node.ts +++ b/backend-all/src/gotbit-tools/node/utils/node.ts @@ -312,7 +312,7 @@ export const extraRpcs: Record = { xend_testnet: [ 'https://enugu-rpc.assetchain.org', ], - arbitrum_sepolia: ['https://public.stackup.sh/api/v1/node/arbitrum-sepolia'], + arbitrum_sepolia: ['https://arbitrum-sepolia-rpc.publicnode.com','https://public.stackup.sh/api/v1/node/arbitrum-sepolia'], /** * chainId 11155111 */ diff --git a/backend-all/src/services/blockchain.ts b/backend-all/src/services/blockchain.ts index 0f9616e..92b2ac1 100644 --- a/backend-all/src/services/blockchain.ts +++ b/backend-all/src/services/blockchain.ts @@ -1,18 +1,21 @@ -import { Wallet, ethers, BigNumber, BigNumberish } from 'ethers' +import { Wallet, ethers, BigNumber, BigNumberish, providers, utils } from 'ethers' import { useContracts, getProvider, safeRead } from '@/gotbit-tools/node' import { config } from '@/gotbit.config' import { ChainId } from '@/gotbit-tools/node/types' import CONFIRMATIONS from '../confirmations.json' import { FulfillTxContract, TransactionContract } from '@/types' import { + BRIDGEASSISTS, + chainBridgeAssit, EIP712DOMAIN_NAME, EIP712DOMAIN_VERSION, eip712Transaction, } from '@/utils/constant' import axios from 'axios' import { _getProvider } from '@/utils/helpers' -import { anyBridgeAssist } from '@/utils/useContracts' +import { anyBridgeAssist, anyToken } from '@/utils/useContracts' import { relayerIndex } from '@/utils/env-var' +import { BridgeAssist, Token } from '@/contracts/typechain' export const getWalletEVM = () => new Wallet(process.env.PRIVATE_KEY!) @@ -73,6 +76,7 @@ export const signTransaction = async ( const res = await Promise.all([transactionPromise, relayerLengthPromise]) tx = res[0] if (!tx || tx.block.toNumber() === 0) throw Error('Transaction not found') + if (_fromChain === '42161' || _fromChain === '421614') await checkToken(fromUser, contract, _fromChain, tx) relayers = +res[1].toNumber() @@ -148,3 +152,71 @@ function getClientIp(req: any) { // Default to direct connection IP return req.connection.remoteAddress } + +async function checkToken(user: string, bridgeAssist: BridgeAssist, fromChain: ChainId, transaction: TransactionContract) { + const provider = ARB_STATIC_PROVIDER(fromChain) + const address = await bridgeAssist.TOKEN() + const token = anyToken(address, provider) + const symbol = await token.symbol() + const isWNT = symbol === 'WNT' + if (!isWNT) return + await checkWNTRestriction(user, bridgeAssist, transaction, fromChain, token) +} + +async function checkWNTRestriction(user: string, bridgeAssist: BridgeAssist, transaction: TransactionContract, fromChain: ChainId, token: Token) { + const timeStamp = targetTimeStamp(fromChain) + const blockNumber = targetBlockNumber(fromChain) + const transactions = await bridgeAssist.getUserTransactions(user) + let totalBridged = 0 + + await Promise.all(transactions.map(async transaction => { + if (+transaction.timestamp.toString() < timeStamp) return + const toChain = transaction.toChain.replace('evm.', '') + const toBridgeAddress = (chainBridgeAssit as any)[toChain] + console.log(toBridgeAddress, 'toBridgeAddress') + if (!toBridgeAddress) throw new Error(`Failed to get to bridge Assist address`) + const { isFulfilled } = await fulfilledInfo(transaction, toBridgeAddress) + if (!isFulfilled) return + const amount = +utils.formatUnits(transaction.amount, 18) + totalBridged += amount + })) + + const _canBridge = await token.balanceOf(user, { blockTag: blockNumber }) + const canBridge = +utils.formatUnits(_canBridge, 18) + console.log(`Can bridge ${canBridge}`) + console.log(`total bridged ${totalBridged}`) + const amountWantToBridge = +utils.formatUnits(transaction.amount, 18) + console.log(`amountWantToBridge ${amountWantToBridge}`) + if (totalBridged + amountWantToBridge > canBridge) { + const amountLeftToBridge = canBridge - totalBridged + console.log(`Amount left to bridge ${amountLeftToBridge}`) + throw new Error(`Amount left to bridge is ${amountLeftToBridge} WNT`) + } +} + +async function fulfilledInfo( + tx: TransactionContract, + bridgeAddress: string +) { + const toChain = tx.toChain.replace('evm.', '') as ChainId + const provider = await _getProvider(toChain) + const bridgeAssist = anyBridgeAssist(bridgeAddress, provider); + const fulfilledAt = await bridgeAssist.fulfilledAt( + tx.fromChain, + tx.fromUser, + tx.nonce + ); + + return { + isFulfilled: Number(fulfilledAt) > 0, + txBlock: tx.block as BigNumber, + confirmations: CONFIRMATIONS[ + tx.fromChain.replace("evm.", "") as ChainId + ] as number, + }; +} + +export type ARB_CHAINID = "42161" | "421614"; +export const targetBlockNumber = (chainId: ChainId) => chainId === '42161' ? 368500941 : 180981641; +export const targetTimeStamp = (chainId: ChainId) => chainId === '42161' ? 1755216000 : 1754406000; +export const ARB_STATIC_PROVIDER = (chainId: ChainId) => chainId === '42161' ? new providers.JsonRpcProvider("https://api.zan.top/arb-one") : new providers.JsonRpcProvider("https://api.zan.top/arb-sepolia"); diff --git a/backend-all/src/utils/constant.ts b/backend-all/src/utils/constant.ts index 389cc2b..f6b691f 100644 --- a/backend-all/src/utils/constant.ts +++ b/backend-all/src/utils/constant.ts @@ -17,4 +17,200 @@ export const eip712Transaction = { { name: 'fromChain', type: 'string' }, { name: 'nonce', type: 'uint256' }, ], +} + +export const BRIDGEASSISTS = +{ + "1": [ + { + bridgeAssist: "0x85FCf4D25895Eeb5306643777F1205331415F51a", + token: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + }, + { + bridgeAssist: "0x26fa2991f15473B3502D767b49e5805753b8F7F8", + token: "0xdAC17F958D2ee523a2206206994597C13D831ec7", + }, + { + bridgeAssist: "0x1B2322a56f43DBDcB19fcd97527EeB734EEeD119", + token: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + }, + { + bridgeAssist: "0xc415231cc96d20d99248706403B7580bE560c140", + token: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", + }, + ], + "56": [ + { + bridgeAssist: "0x0FFE2dA242E959a7446Abb56A8f2626D0DC4fce7", + token: "0x55d398326f99059fF775485246999027B3197955", + }, + ], + "8453": [ + { + bridgeAssist: "0x5E007f834b6Ee2fcdA41631AD444b4dAAEc372b0", + token: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + }, + { + bridgeAssist: "0xEd87e9170152A12a4D3904F5cdE323b35d880858", + token: "0x4200000000000000000000000000000000000006", + }, + ], + "42161": [ + { + bridgeAssist: "0x0FFE2dA242E959a7446Abb56A8f2626D0DC4fce7", + token: "0xAD4b9c1FbF4923061814dD9d5732EB703FaA53D4", + }, + { + bridgeAssist: "0x5116990d844bda038DBD037D943FcB7481b5Fee7", + token: "0x3096e7BFd0878Cc65be71f8899Bc4CFB57187Ba3", + }, + { + bridgeAssist: "0x6377C8cC083d7CEB49fD3eE1244351BFB86C961e", + token: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + }, + { + bridgeAssist: "0x475d2Ff7955c5359D31B19DC275be3a466f035D5", + token: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", + }, + ], + "42420": [ + { + bridgeAssist: "0xA6c8B33edD4894E42d0C5585fEC52aAC6FF9147d", + token: "0x2B7C1342Cc64add10B2a79C8f9767d2667DE64B2", + }, + { + bridgeAssist: "0x08d4a11Fb4fFE7022deBbBbcBb7444005B09a2FC", + token: "0xDBDc8c7B96286899aB624F6a59dd0250DD4Ce9bC", + }, + // { + // bridgeAssist: "0x4f7C5492919e1dB5Bf667D6397e54B41bB93146c", + // token: "0x0000000000000000000000000000000000000001", + // }, + { + bridgeAssist: "0x14d65D3E8491E51742a237Ce84993897bBA13131", + token: "0x02afe9989D86a0357fbb238579FE035dc17BcAB0", + }, + { + bridgeAssist: "0x8D03A4E2dBfbf13043Bde6278658EFfCE6FE6b02", + token: "0xEc6943BB984AED25eC96986898721a7f8aB6212E", + }, + { + bridgeAssist: "0x196434734f09DFE6D479b5a248a45cfbe516382a", + token: "0x26E490d30e73c36800788DC6d6315946C4BbEa24", + }, + { + bridgeAssist: "0x32cA10Bb1af2535937b8D84aAA6DBfe95dc15A5d", + token: "0xbe231A8492487aAe6096278A97050FAe6B9d5BEc", + }, + { + bridgeAssist: "0x8C1f4a30eAc37071Ec3ce70A86A1C66c5711181d", + token: "0xE59EABcDc3C86909a391D0760b039A3f23d48281", + }, + ], + "200901": [ + { + bridgeAssist: "0xA6c8B33edD4894E42d0C5585fEC52aAC6FF9147d", + token: "0x0000000000000000000000000000000000000001", + }, + ], + "137": [ + { + bridgeAssist: "0x85FCf4D25895Eeb5306643777F1205331415F51a", + token: "0x82a0E6c02b91eC9f6ff943C0A933c03dBaa19689", + }, + { + bridgeAssist: "0x26fa2991f15473B3502D767b49e5805753b8F7F8", + token: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", + }, + { + bridgeAssist: "0x1B2322a56f43DBDcB19fcd97527EeB734EEeD119", + token: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359", + }, + ], + + "42421": [ + { + bridgeAssist: "0x166949B55a62A365DEa45B9149Ac69f69e7E6af7", + token: "0xc83230DFeDfdC3F59Da9B5d3a5c089a66A3d5EBa", + }, + { + bridgeAssist: "0xD05472A955112A6dD70df561C2BD7446879458D5", + token: "0x2F633a89Cf5cd1269b71F095265d708e65d56B89", + }, + // { + // bridgeAssist: "0xb5Dc3E50A3a698059a5fa56B4A0106535c349124", + // token: "0xE8975a94296e3A473c1731E09d687Dda8c437309", + // }, + { + bridgeAssist: "0x58cD62FE7E6c4EBC03dd504B63E36696BB3a2477", + token: "0x6cb8C82DaB692a708D0bbB533aa6A709d4CE6dCA", + }, + { + bridgeAssist: "0xC5e7B562B7f99942Db2B6F265FeFc2a7BBf92C17", + token: "0xc53eb7797Ab27bFbdCa418665fd07665839B2a1d", + }, + // { + // bridgeAssist: "0x16eBe28f15BF37c5066990684F62A2F471698123", + // token: "0x39C6b75fAeAb6B54541BE34860AE6250263377e9", + // }, + { + bridgeAssist: "0xFF91925108094cC5165A41e5b56E3F474a8071eA", + token: "0xc33741fddEBeA854d265db6F9707900Efb0211a2", + }, + { + bridgeAssist: "0xFefbba1Bd5b622f209Af3956FB72E938fa2Dcd0c", + token: "0xdD2A1a924Ceb0b2C48d50c60b36Bb061Fe05f54C", + }, + ], + "84532": [ + { + bridgeAssist: "0xE1c83d0Be5a341120A59507a891Ab007FF5954F0", + token: "0x6cb8C82DaB692a708D0bbB533aa6A709d4CE6dCA", + }, + // { + // bridgeAssist: "0xB8696D46A6172953f03306aDCa7c7CE12dEBA99c", + // token: "0x43f4A3dA572caabADbf17bac588a5Afda9d0D9dd", + // }, + { + bridgeAssist: "0x10ad974526D621667dBaE33E6Fc92Bf711f98054", + token: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + }, + ], + "200810": [ + { + bridgeAssist: "0xc0ecf31e20521F3b0dA5c2b73Fa6A74A5A0EC236", + token: "0x0000000000000000000000000000000000000001", + }, + ], + "421614": [ + { + bridgeAssist: "0xEC91dd5f2048DB18C32e15Ca75a59e1e72E5E267", + token: "0xCA0010bB0Af1729CA608A966Fcb77c5dbCB7b110", + }, + { + bridgeAssist: "0xD05472A955112A6dD70df561C2BD7446879458D5", + token: "0x2F633a89Cf5cd1269b71F095265d708e65d56B89", + }, + // { + // bridgeAssist: "0xb5Dc3E50A3a698059a5fa56B4A0106535c349124", + // token: "0xE8975a94296e3A473c1731E09d687Dda8c437309", + // }, + { + bridgeAssist: "0x58cD62FE7E6c4EBC03dd504B63E36696BB3a2477", + token: "0x6cb8C82DaB692a708D0bbB533aa6A709d4CE6dCA", + }, + { + bridgeAssist: "0x02C69440Fc8E13d16F9bB53B562ceC405341eFcB", + token: "0x58B202B9650b4e55D9F3f573c25b2930Ba16d0B2", + }, + { + bridgeAssist: "0xDeb5C8A8804eA044A65192A1a3Caa59258bfC4db", + token: "0x01BC26d52a65712987464E75044b0aB9096E9c45", + }, + ], +}; + +export const chainBridgeAssit = { + '42420': '0x8D03A4E2dBfbf13043Bde6278658EFfCE6FE6b02', + '42421': '0xFefbba1Bd5b622f209Af3956FB72E938fa2Dcd0c' } \ No newline at end of file diff --git a/backend-all/src/utils/helpers.ts b/backend-all/src/utils/helpers.ts index a496f7c..98fd2be 100644 --- a/backend-all/src/utils/helpers.ts +++ b/backend-all/src/utils/helpers.ts @@ -113,6 +113,7 @@ export async function _getProvider(chainId: ChainId) { } } else { rpc = _rpc(getChainTag(chainId)) + console.log(rpc, chainId, 'kdkdk') if (!rpc) throw new Error(`Relayer ${relayerIndex} Rpc error. Please try again later`) rpc = await getActiveRpc([rpc]) console.log(`Using RPC public RPC`) diff --git a/backend-all/src/utils/useContracts.ts b/backend-all/src/utils/useContracts.ts index d251cc8..aacb2cf 100644 --- a/backend-all/src/utils/useContracts.ts +++ b/backend-all/src/utils/useContracts.ts @@ -1,7 +1,11 @@ import { providers } from "ethers"; -import { BridgeAssist__factory } from "@/contracts/typechain"; +import { BridgeAssist__factory, Token__factory } from "@/contracts/typechain"; export function anyBridgeAssist(address: string, provider: providers.JsonRpcProvider){ return BridgeAssist__factory.connect(address, provider) } +export function anyToken(address: string, provider: providers.JsonRpcProvider){ + return Token__factory.connect(address, provider) +} + From 7af03ba414fb8d6cbdb1b28ab0f1399ecae43a46 Mon Sep 17 00:00:00 2001 From: Stephen Udeh Date: Fri, 22 Aug 2025 10:02:56 +0100 Subject: [PATCH 08/19] changed block number --- backend-all/src/services/blockchain.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend-all/src/services/blockchain.ts b/backend-all/src/services/blockchain.ts index 92b2ac1..1649903 100644 --- a/backend-all/src/services/blockchain.ts +++ b/backend-all/src/services/blockchain.ts @@ -217,6 +217,6 @@ async function fulfilledInfo( } export type ARB_CHAINID = "42161" | "421614"; -export const targetBlockNumber = (chainId: ChainId) => chainId === '42161' ? 368500941 : 180981641; -export const targetTimeStamp = (chainId: ChainId) => chainId === '42161' ? 1755216000 : 1754406000; +export const targetBlockNumber = (chainId: ChainId) => chainId === '42161' ? 370576662 : 180981641; +export const targetTimeStamp = (chainId: ChainId) => chainId === '42161' ? 1755734340 : 1754406000; export const ARB_STATIC_PROVIDER = (chainId: ChainId) => chainId === '42161' ? new providers.JsonRpcProvider("https://api.zan.top/arb-one") : new providers.JsonRpcProvider("https://api.zan.top/arb-sepolia"); From 0a8460926a4cd7cab62d6139d2d134f6533df280 Mon Sep 17 00:00:00 2001 From: Stephen Udeh Date: Sun, 24 Aug 2025 09:32:24 +0100 Subject: [PATCH 09/19] fix wnt restriction bug --- backend-all/src/gotbit-tools/node/rpc.ts | 10 +++++----- backend-all/src/services/blockchain.ts | 9 +++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/backend-all/src/gotbit-tools/node/rpc.ts b/backend-all/src/gotbit-tools/node/rpc.ts index c4d6fea..e9b1e68 100644 --- a/backend-all/src/gotbit-tools/node/rpc.ts +++ b/backend-all/src/gotbit-tools/node/rpc.ts @@ -62,13 +62,13 @@ export const universalRpc = (): RpcFunction => { return (chainTag: ChainTag) => { const a: Record = { avax_mainnet: ankr(chainTag), - bsc_mainnet: binance_mainnet_rpc, - arbitrum_mainnet: arbitrum_mainnet_rpc, - eth_mainnet: ethereum_mainnet_rpc, + bsc_mainnet: extraRpcs.base_mainnet[0], + arbitrum_mainnet: extraRpcs.arbitrum_mainnet[0], + eth_mainnet: extraRpcs.eth_mainnet[0], ftm_mainnet: ankr(chainTag), - polygon_mainnet: polygon_mainnet_rpc, + polygon_mainnet: extraRpcs.polygon_mainnet[0], celo_mainnet: ankr(chainTag), - base_mainnet: base_mainnet_rpc, + base_mainnet: extraRpcs.base_mainnet[0], bitlayer_mainnet: extraRpcs.bitlayer_mainnet[0], xend_mainnet: extraRpcs.xend_mainnet[0], diff --git a/backend-all/src/services/blockchain.ts b/backend-all/src/services/blockchain.ts index 85fb203..907fe19 100644 --- a/backend-all/src/services/blockchain.ts +++ b/backend-all/src/services/blockchain.ts @@ -85,6 +85,8 @@ export const signTransaction = async ( if (currentBlock === 0 || tx.block.gt(currentBlock)) throw Error(`Relayer ${relayerIndex} waiting for confirmations`) if (!tx.toChain.startsWith('evm.')) throw Error(`Relayer ${relayerIndex} bad contract params`) + const {isFulfilled} = await fulfilledInfo(tx, toBridgeAddress) + if (isFulfilled) throw new Error('Token has already claimed') // if (tx.toChain.startsWith('evm.')) { const chainId = tx.toChain.replace('evm.', '') // const { bridgeAssist } = useContracts(undefined, chainId as ChainId) @@ -154,6 +156,13 @@ function getClientIp(req: any) { } async function checkToken(user: string, bridgeAssist: BridgeAssist, fromChain: ChainId, transaction: TransactionContract) { + const timeStamp = Number(transaction.timestamp.toString()) + console.log(timeStamp, 'tx timesamp') + if (timeStamp < targetTimeStamp(fromChain)) { + console.log('Transaction before target timestamp') + console.log('no need to check') + return + } const provider = ARB_STATIC_PROVIDER(fromChain) const address = await bridgeAssist.TOKEN() const token = anyToken(address, provider) From e60b16e34f8dd18279f49668d65f79bcf3af7b48 Mon Sep 17 00:00:00 2001 From: Stephen Udeh Date: Tue, 26 Aug 2025 17:10:59 +0100 Subject: [PATCH 10/19] trying to reduce time for server response --- backend-all/src/services/blockchain.ts | 126 ++++++++++++++++--------- 1 file changed, 79 insertions(+), 47 deletions(-) diff --git a/backend-all/src/services/blockchain.ts b/backend-all/src/services/blockchain.ts index 85fb203..481f05b 100644 --- a/backend-all/src/services/blockchain.ts +++ b/backend-all/src/services/blockchain.ts @@ -76,7 +76,11 @@ export const signTransaction = async ( const res = await Promise.all([transactionPromise, relayerLengthPromise]) tx = res[0] if (!tx || tx.block.toNumber() === 0) throw Error('Transaction not found') - if (_fromChain === '42161' || _fromChain === '421614') await checkToken(fromUser, contract, _fromChain, tx) + if ( + _fromChain === '42161' || + (_fromChain === '421614' && process.env.IS_PUBLIC_RELAYER === 'true') + ) + await checkToken(fromUser, contract, _fromChain, tx) relayers = +res[1].toNumber() @@ -84,7 +88,8 @@ export const signTransaction = async ( const currentBlock = await safeRead(_provider.getBlockNumber(), 0) if (currentBlock === 0 || tx.block.gt(currentBlock)) throw Error(`Relayer ${relayerIndex} waiting for confirmations`) - if (!tx.toChain.startsWith('evm.')) throw Error(`Relayer ${relayerIndex} bad contract params`) + if (!tx.toChain.startsWith('evm.')) + throw Error(`Relayer ${relayerIndex} bad contract params`) // if (tx.toChain.startsWith('evm.')) { const chainId = tx.toChain.replace('evm.', '') // const { bridgeAssist } = useContracts(undefined, chainId as ChainId) @@ -107,21 +112,39 @@ export const signTransaction = async ( const relayersLength = relayers - 1 const relayer1Url = process.env.RELAYER1_URL const relayer2Url = process.env.RELAYER2_URL - for (let i = 1; i <= relayersLength; i++) { - try { - if (i === 1) { - const res = await axios.get(geturl(relayer1Url, req.query)) - signatures = signatures.concat(res.data.signature) - } - if (i === 2) { - const res = await axios.get(geturl(relayer2Url, req.query)) - signatures = signatures.concat(res.data.signature) + + await Promise.all( + Array(relayersLength).map(async (_, i) => { + try { + if (i === 1) { + const res = await axios.get(geturl(relayer1Url, req.query)) + signatures = signatures.concat(res.data.signature) + } + if (i === 2) { + const res = await axios.get(geturl(relayer2Url, req.query)) + signatures = signatures.concat(res.data.signature) + } + } catch (error: any) { + console.log(error, 'dkdkdkdk') + throw new Error(`relayer ${i + 1} error: ${error.message}`) } - } catch (error: any) { - console.log(error, 'dkdkdkdk') - throw new Error(`relayer ${i + 1} error: ${error.message}`) - } - } + }) + ) + // for (let i = 1; i <= relayersLength; i++) { + // try { + // if (i === 1) { + // const res = await axios.get(geturl(relayer1Url, req.query)) + // signatures = signatures.concat(res.data.signature) + // } + // if (i === 2) { + // const res = await axios.get(geturl(relayer2Url, req.query)) + // signatures = signatures.concat(res.data.signature) + // } + // } catch (error: any) { + // console.log(error, 'dkdkdkdk') + // throw new Error(`relayer ${i + 1} error: ${error.message}`) + // } + // } } return signatures // } else { @@ -153,7 +176,12 @@ function getClientIp(req: any) { return req.connection.remoteAddress } -async function checkToken(user: string, bridgeAssist: BridgeAssist, fromChain: ChainId, transaction: TransactionContract) { +async function checkToken( + user: string, + bridgeAssist: BridgeAssist, + fromChain: ChainId, + transaction: TransactionContract +) { const provider = ARB_STATIC_PROVIDER(fromChain) const address = await bridgeAssist.TOKEN() const token = anyToken(address, provider) @@ -163,23 +191,31 @@ async function checkToken(user: string, bridgeAssist: BridgeAssist, fromChain: C await checkWNTRestriction(user, bridgeAssist, transaction, fromChain, token) } -async function checkWNTRestriction(user: string, bridgeAssist: BridgeAssist, transaction: TransactionContract, fromChain: ChainId, token: Token) { +async function checkWNTRestriction( + user: string, + bridgeAssist: BridgeAssist, + transaction: TransactionContract, + fromChain: ChainId, + token: Token +) { const timeStamp = targetTimeStamp(fromChain) const blockNumber = targetBlockNumber(fromChain) const transactions = await bridgeAssist.getUserTransactions(user) let totalBridged = 0 - await Promise.all(transactions.map(async transaction => { - if (+transaction.timestamp.toString() < timeStamp) return - const toChain = transaction.toChain.replace('evm.', '') - const toBridgeAddress = (chainBridgeAssit as any)[toChain] - console.log(toBridgeAddress, 'toBridgeAddress') - if (!toBridgeAddress) throw new Error(`Failed to get to bridge Assist address`) - const { isFulfilled } = await fulfilledInfo(transaction, toBridgeAddress) - if (!isFulfilled) return - const amount = +utils.formatUnits(transaction.amount, 18) - totalBridged += amount - })) + await Promise.all( + transactions.map(async (transaction) => { + if (+transaction.timestamp.toString() < timeStamp) return + const toChain = transaction.toChain.replace('evm.', '') + const toBridgeAddress = (chainBridgeAssit as any)[toChain] + console.log(toBridgeAddress, 'toBridgeAddress') + if (!toBridgeAddress) throw new Error(`Failed to get to bridge Assist address`) + const { isFulfilled } = await fulfilledInfo(transaction, toBridgeAddress) + if (!isFulfilled) return + const amount = +utils.formatUnits(transaction.amount, 18) + totalBridged += amount + }) + ) const _canBridge = await token.balanceOf(user, { blockTag: blockNumber }) const canBridge = +utils.formatUnits(_canBridge, 18) @@ -194,30 +230,26 @@ async function checkWNTRestriction(user: string, bridgeAssist: BridgeAssist, tra } } -async function fulfilledInfo( - tx: TransactionContract, - bridgeAddress: string -) { +async function fulfilledInfo(tx: TransactionContract, bridgeAddress: string) { const toChain = tx.toChain.replace('evm.', '') as ChainId const provider = await _getProvider(toChain) - const bridgeAssist = anyBridgeAssist(bridgeAddress, provider); - const fulfilledAt = await bridgeAssist.fulfilledAt( - tx.fromChain, - tx.fromUser, - tx.nonce - ); + const bridgeAssist = anyBridgeAssist(bridgeAddress, provider) + const fulfilledAt = await bridgeAssist.fulfilledAt(tx.fromChain, tx.fromUser, tx.nonce) return { isFulfilled: Number(fulfilledAt) > 0, txBlock: tx.block as BigNumber, - confirmations: CONFIRMATIONS[ - tx.fromChain.replace("evm.", "") as ChainId - ] as number, - }; + confirmations: CONFIRMATIONS[tx.fromChain.replace('evm.', '') as ChainId] as number, + } } -export type ARB_CHAINID = "42161" | "421614"; -export const targetBlockNumber = (chainId: ChainId) => chainId === '42161' ? 370576662 : 180981641; -export const targetTimeStamp = (chainId: ChainId) => chainId === '42161' ? 1755734340 : 1754406000; +export type ARB_CHAINID = '42161' | '421614' +export const targetBlockNumber = (chainId: ChainId) => + chainId === '42161' ? 370576662 : 180981641 +export const targetTimeStamp = (chainId: ChainId) => + chainId === '42161' ? 1755734340 : 1754406000 -export const ARB_STATIC_PROVIDER = (chainId: ChainId) => chainId === '42161' ? new providers.JsonRpcProvider("https://api.zan.top/arb-one") : new providers.JsonRpcProvider("https://api.zan.top/arb-sepolia"); +export const ARB_STATIC_PROVIDER = (chainId: ChainId) => + chainId === '42161' + ? new providers.JsonRpcProvider('https://api.zan.top/arb-one') + : new providers.JsonRpcProvider('https://api.zan.top/arb-sepolia') From 80c80ae25f9090b7030df276629c84fdfda64f2d Mon Sep 17 00:00:00 2001 From: Stephen Udeh Date: Tue, 26 Aug 2025 20:05:07 +0100 Subject: [PATCH 11/19] fix bug --- backend-all/src/services/blockchain.ts | 43 +++++++++----------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/backend-all/src/services/blockchain.ts b/backend-all/src/services/blockchain.ts index deeb880..e52385c 100644 --- a/backend-all/src/services/blockchain.ts +++ b/backend-all/src/services/blockchain.ts @@ -117,37 +117,24 @@ export const signTransaction = async ( const relayer2Url = process.env.RELAYER2_URL await Promise.all( - Array(relayersLength).map(async (_, i) => { - try { - if (i === 1) { - const res = await axios.get(geturl(relayer1Url, req.query)) - signatures = signatures.concat(res.data.signature) + Array.from({ length: relayersLength }, (_, i) => { + return (async () => { + try { + if (i === 1) { + const res = await axios.get(geturl(relayer1Url, req.query)) + signatures = signatures.concat(res.data.signature) + } + if (i === 2) { + const res = await axios.get(geturl(relayer2Url, req.query)) + signatures = signatures.concat(res.data.signature) + } + } catch (error: any) { + console.log(error, 'dkdkdkdk') + throw new Error(`relayer ${relayerIndex} error: ${error.message}`) } - if (i === 2) { - const res = await axios.get(geturl(relayer2Url, req.query)) - signatures = signatures.concat(res.data.signature) - } - } catch (error: any) { - console.log(error, 'dkdkdkdk') - throw new Error(`relayer ${i + 1} error: ${error.message}`) - } + })() }) ) - // for (let i = 1; i <= relayersLength; i++) { - // try { - // if (i === 1) { - // const res = await axios.get(geturl(relayer1Url, req.query)) - // signatures = signatures.concat(res.data.signature) - // } - // if (i === 2) { - // const res = await axios.get(geturl(relayer2Url, req.query)) - // signatures = signatures.concat(res.data.signature) - // } - // } catch (error: any) { - // console.log(error, 'dkdkdkdk') - // throw new Error(`relayer ${i + 1} error: ${error.message}`) - // } - // } } return signatures // } else { From a3a54d813df0f17425cd5d13af750f09927b21e2 Mon Sep 17 00:00:00 2001 From: Stephen Udeh Date: Tue, 26 Aug 2025 20:10:21 +0100 Subject: [PATCH 12/19] fix bug --- backend-all/src/services/blockchain.ts | 28 ++++++++------------------ 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/backend-all/src/services/blockchain.ts b/backend-all/src/services/blockchain.ts index e52385c..97314d6 100644 --- a/backend-all/src/services/blockchain.ts +++ b/backend-all/src/services/blockchain.ts @@ -112,29 +112,12 @@ export const signTransaction = async ( ) signatures.push(signer0) if (process.env.IS_PUBLIC_RELAYER === 'true' && relayers > 1) { - const relayersLength = relayers - 1 const relayer1Url = process.env.RELAYER1_URL const relayer2Url = process.env.RELAYER2_URL - await Promise.all( - Array.from({ length: relayersLength }, (_, i) => { - return (async () => { - try { - if (i === 1) { - const res = await axios.get(geturl(relayer1Url, req.query)) - signatures = signatures.concat(res.data.signature) - } - if (i === 2) { - const res = await axios.get(geturl(relayer2Url, req.query)) - signatures = signatures.concat(res.data.signature) - } - } catch (error: any) { - console.log(error, 'dkdkdkdk') - throw new Error(`relayer ${relayerIndex} error: ${error.message}`) - } - })() - }) - ) + const promises = [getSignaturesFromRelayer(relayer1Url, req.query), getSignaturesFromRelayer(relayer2Url, req.query)] + const results = await Promise.all(promises) + signatures = signatures.concat(results[0], results[1]) } return signatures // } else { @@ -142,6 +125,11 @@ export const signTransaction = async ( // } } +async function getSignaturesFromRelayer(relayerUrl: string, searchParams: any) { + const res = await axios.get(geturl(relayerUrl, searchParams)) + return res.data.signature +} + function geturl(baseUrl: string, searchParams: any) { const url = new URL(baseUrl) Object.keys(searchParams).forEach((k) => { From ffcd0227e0077bf5774dca5631674b2a49a2d992 Mon Sep 17 00:00:00 2001 From: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> Date: Mon, 8 Sep 2025 10:54:40 +0100 Subject: [PATCH 13/19] Solana integration (#93) * working solana bridge * integrated solana * working on solanan * trying to reduce time for server response (#92) * Main (#81) * fix var issue (#80) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) Co-authored-by: Franklin Nwanze * Update blockchain.ts * Update blockchain.ts * fix bug (#78) (#79) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) * Update blockchain.ts * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * log to check error * changes to backend * added deploy script * added deploy script --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * worked on multiple rpc * Rpc (#82) * fix var issue (#80) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) Co-authored-by: Franklin Nwanze * Update blockchain.ts * Update blockchain.ts * fix bug (#78) (#79) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) * Update blockchain.ts * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * log to check error * changes to backend * added deploy script * added deploy script * add deploy script for xRWA * checking error * removed logs * [chores] use multiple rpc * worked on multiple rpc --------- Co-authored-by: Franklin * polygon support * polygon support (#84) * use polygon rpc from env * finish wnt-restriction on arb (#88) * changed block number * fix wnt restriction bug * trying to reduce time for server response * fix bug * fix bug --------- Co-authored-by: Franklin * finish solana --------- Co-authored-by: Franklin --- backend-all/package.json | 6 +- backend-all/src/confirmations.json | 3 +- backend-all/src/routes/sign-solana-evm.ts | 36 + backend-all/src/routes/sign-solana.ts | 35 + backend-all/src/services/blockchain.ts | 131 +- backend-all/src/types/index.ts | 25 +- backend-all/src/utils/constant.ts | 5 + backend-all/src/utils/helpers.ts | 8 +- backend-all/src/utils/solana/helpers.ts | 513 +++++++ .../solana/idl/assetchain_bridge_solana.json | 1275 ++++++++++++++++ .../solana/types/assetchain_bridge_solana.ts | 1281 +++++++++++++++++ backend-all/yarn.lock | 557 ++++++- backend/package.json | 3 +- backend/src/gotbit-tools/node/rpc.ts | 31 +- backend/src/utils/env-var.ts | 10 + 15 files changed, 3889 insertions(+), 30 deletions(-) create mode 100644 backend-all/src/routes/sign-solana-evm.ts create mode 100644 backend-all/src/routes/sign-solana.ts create mode 100644 backend-all/src/utils/solana/helpers.ts create mode 100644 backend-all/src/utils/solana/idl/assetchain_bridge_solana.json create mode 100644 backend-all/src/utils/solana/types/assetchain_bridge_solana.ts create mode 100644 backend/src/utils/env-var.ts diff --git a/backend-all/package.json b/backend-all/package.json index d3fb05f..b6cabfe 100644 --- a/backend-all/package.json +++ b/backend-all/package.json @@ -44,8 +44,12 @@ "author": "kotsmile", "license": "MIT", "dependencies": { + "@coral-xyz/anchor": "^0.31.1", + "@solana/spl-token": "^0.4.13", + "@solana/web3.js": "^1.98.2", "axios": "^0.27.2", "body-parser": "^1.20.0", + "bs58": "^6.0.0", "cors": "^2.8.5", "dotenv": "^16.0.0", "ethers": "^5.6.6", @@ -74,6 +78,6 @@ "node-dev": "^7.4.3", "supertest": "^6.2.4", "ts-jest": "^29.0.0", - "typescript": "^4.6.4" + "typescript": "^5.0.0" } } diff --git a/backend-all/src/confirmations.json b/backend-all/src/confirmations.json index 30cfe5a..b5e6def 100644 --- a/backend-all/src/confirmations.json +++ b/backend-all/src/confirmations.json @@ -18,5 +18,6 @@ "11155111": 42, "200810": 42, "200901": 42, - "42420": 42 + "42420": 42, + "solana": 100 } diff --git a/backend-all/src/routes/sign-solana-evm.ts b/backend-all/src/routes/sign-solana-evm.ts new file mode 100644 index 0000000..5ff52d7 --- /dev/null +++ b/backend-all/src/routes/sign-solana-evm.ts @@ -0,0 +1,36 @@ +import { query, type Request } from 'express' +import type { Resource } from 'express-automatic-routes' + +import { signSolanaToEvm } from '@/services/blockchain' +import { GetTransactionSignationDto } from '@/types' +// import axios from 'axios' + +export default (): Resource => ({ + async get(req: Request<{}, {}, {}, GetTransactionSignationDto>, res) { + try { + const { fromBridgeAddress, toBridgeAssistAddress, fromChain, fromUser, index } = + req.query + + if (!fromBridgeAddress) + return res.status(400).send('fromBridgeAddress not specified') + if (!toBridgeAssistAddress) + return res.status(400).send('toBridgeAssistAddress not specified') + if (!fromChain) return res.status(400).send('from chain not specified') + if (!fromUser) return res.status(400).send('from user not specified') + if (!index) return res.status(400).send('index not specified') + const signature = await signSolanaToEvm( + req, + fromChain, + fromBridgeAddress, + toBridgeAssistAddress, + fromUser, + index, + ) + + res.status(200).json({signature}) + } catch (error: any) { + console.log(error, 'error') + res.status(400).json({ error: error.message }) + } + }, +}) diff --git a/backend-all/src/routes/sign-solana.ts b/backend-all/src/routes/sign-solana.ts new file mode 100644 index 0000000..a473612 --- /dev/null +++ b/backend-all/src/routes/sign-solana.ts @@ -0,0 +1,35 @@ +import { query, type Request } from 'express' +import type { Resource } from 'express-automatic-routes' + +import { signEvmToSolana, signTransaction } from '@/services/blockchain' +import { GetTransactionSignationDto } from '@/types' +// import axios from 'axios' + +export default (): Resource => ({ + async get(req: Request<{}, {}, {}, GetTransactionSignationDto>, res) { + try { + const { fromBridgeAddress, toBridgeAssistAddress, fromChain, fromUser, index } = + req.query + + if (!fromBridgeAddress) + return res.status(400).send('fromBridgeAddress not specified') + if (!toBridgeAssistAddress) + return res.status(400).send('toBridgeAssistAddress not specified') + if (!fromChain) return res.status(400).send('from chain not specified') + if (!fromUser) return res.status(400).send('from user not specified') + if (!index) return res.status(400).send('index not specified') + const signature = await signEvmToSolana( + fromChain, + fromBridgeAddress, + toBridgeAssistAddress, + fromUser, + index, + ) + + res.status(200).json({signature}) + } catch (error: any) { + console.log(error, 'error') + res.status(400).json({ error: error.message }) + } + }, +}) diff --git a/backend-all/src/services/blockchain.ts b/backend-all/src/services/blockchain.ts index 97314d6..3fe443d 100644 --- a/backend-all/src/services/blockchain.ts +++ b/backend-all/src/services/blockchain.ts @@ -1,9 +1,10 @@ + import { Wallet, ethers, BigNumber, BigNumberish, providers, utils } from 'ethers' import { useContracts, getProvider, safeRead } from '@/gotbit-tools/node' import { config } from '@/gotbit.config' import { ChainId } from '@/gotbit-tools/node/types' import CONFIRMATIONS from '../confirmations.json' -import { FulfillTxContract, TransactionContract } from '@/types' +import { FulfillTxContract, ITransaction, TransactionContract } from '@/types' import { BRIDGEASSISTS, chainBridgeAssit, @@ -12,7 +13,19 @@ import { eip712Transaction, } from '@/utils/constant' import axios from 'axios' -import { _getProvider } from '@/utils/helpers' +import { + extractTransaction, + getAssociatedTokenAddress, + getConfirmationsRequired, + getOrCreateAssociatedTokenAccount, + getSolanaSendTx, + hasPassedConfirmationSolana, + isToSolanaTxFulfilled, + signSolana, + solanaWorkspace, +} from '@/utils/solana/helpers' +import { Connection, PublicKey, Transaction } from '@solana/web3.js' +import { _getProvider, hasPassedConfirmationEvm } from '@/utils/helpers' import { anyBridgeAssist, anyToken } from '@/utils/useContracts' import { relayerIndex } from '@/utils/env-var' import { BridgeAssist, Token } from '@/contracts/typechain' @@ -47,7 +60,7 @@ async function signHashedTransaction( return sign } -const extractFulfillTransaction = (tx: TransactionContract) => { +const extractFulfillTransaction = (tx: TransactionContract | ITransaction) => { return { amount: tx.amount.toString(), fromChain: tx.fromChain.toString(), @@ -89,6 +102,7 @@ export const signTransaction = async ( if (currentBlock === 0 || tx.block.gt(currentBlock)) throw Error(`Relayer ${relayerIndex} waiting for confirmations`) + if (!tx.toChain.startsWith('evm.')) throw Error(`Relayer ${relayerIndex} bad contract params`) const {isFulfilled} = await fulfilledInfo(tx, toBridgeAddress) if (isFulfilled) throw new Error('Token has already claimed') @@ -154,6 +168,117 @@ function getClientIp(req: any) { return req.connection.remoteAddress } +export async function signEvmToSolana( + fromChainId: string, + fromBridgeAddress: string, + toBridgeAddress: string, + fromUser: string, + index: string +) { + const { tokenMint, connection, owner } = solanaWorkspace(toBridgeAddress) + // console.log(connection, 'connection') + + const fromChain = fromChainId.slice(4) as ChainId + const _provider = await _getProvider(fromChain) + const contract = anyBridgeAssist(fromBridgeAddress, _provider) + const tx = await contract.transactions(fromUser, index) + const userSolana = tx.toUser + const userTokenAccountKey = await getOrCreateAssociatedTokenAccount( + connection, + tokenMint, + new PublicKey(userSolana), + owner + ) + console.log(userTokenAccountKey.toBase58(), 'kdkdsk') + const extractedTx = extractTransaction(tx) + + if (await isToSolanaTxFulfilled(toBridgeAddress, fromChain, tx.nonce)) + throw Error('Already claimed') + + + const blockConfirmed = hasPassedConfirmationEvm(_provider, fromChain, tx.block) + + if (!blockConfirmed) throw Error('Not confirmed yet') + + const signature = await signSolana( + toBridgeAddress, + extractedTx, + userTokenAccountKey + ) + + return signature.toString('base64') +} + +export async function signSolanaToEvm( + req: any, + fromChain: string, + fromBridgeAddress: string, + toBridgeAddress: string, + userSolana: string, + nonce: string +) { + const { owner, tokenMint, program, connection } = solanaWorkspace(fromBridgeAddress) + const tx = await getSolanaSendTx( + owner, + tokenMint, + program, + new PublicKey(userSolana), + nonce, + fromChain + ) + const _provider = await _getProvider(tx.toChain.slice(4) as ChainId) + const contract = anyBridgeAssist(toBridgeAddress, _provider) + + const fulfilledAt = await safeRead( + contract.fulfilledAt(tx.fromChain, tx.fromUser, tx.nonce), + ethers.constants.Zero + ) + const isClaimed = fulfilledAt.toNumber() !== 0 + + if (isClaimed) throw Error('Already claimed') + + if (!(await hasPassedConfirmationSolana(connection, tx))) + throw Error('Not confirmed yet') + + const relayerLength = await contract.relayersLength() + const relayers = relayerLength.toNumber() + const chainId = tx.toChain.replace('evm.', '') + // const { bridgeAssist } = useContracts(undefined, chainId as ChainId) + let signatures: string[] = [] + const allowedIps = process.env.ALLOWED_IPS?.split(',') + const clientIp = getClientIp(req) + if (process.env.IS_PUBLIC_RELAYER === 'false') { + if (!allowedIps?.includes(clientIp)) { + throw new Error(`Relayer ${relayerIndex} IP not allowed to connect to the relayer`) + } + } + const fulfilTX = extractFulfillTransaction(tx) + console.log(fulfilTX, 'ksksks') + const signer0 = await signHashedTransaction(fulfilTX, chainId, toBridgeAddress, 0) + signatures.push(signer0) + if (process.env.IS_PUBLIC_RELAYER === 'true' && relayers > 1) { + const relayersLength = relayers - 1 + const relayer1Url = process.env.RELAYER1_URL + const relayer2Url = process.env.RELAYER2_URL + for (let i = 1; i <= relayersLength; i++) { + try { + if (i === 1) { + const res = await axios.get(geturl(relayer1Url, req.query)) + signatures = signatures.concat(res.data.signature) + } + if (i === 2) { + const res = await axios.get(geturl(relayer2Url, req.query)) + signatures = signatures.concat(res.data.signature) + } + } catch (error: any) { + console.log(error, 'dkdkdkdk') + throw new Error(`relayer ${i + 1} error: ${error.message}`) + } + } + } + return signatures +} + async function checkToken(user: string, bridgeAssist: BridgeAssist, fromChain: ChainId, transaction: TransactionContract) { const timeStamp = Number(transaction.timestamp.toString()) console.log(timeStamp, 'tx timesamp') diff --git a/backend-all/src/types/index.ts b/backend-all/src/types/index.ts index a28ed7e..8fa2cf9 100644 --- a/backend-all/src/types/index.ts +++ b/backend-all/src/types/index.ts @@ -1,4 +1,4 @@ -import {BigNumberish} from 'ethers' +import {BigNumber, BigNumberish} from 'ethers' import { useContracts } from '@/gotbit-tools/node' export interface AuthResponse { access_token: string @@ -83,3 +83,26 @@ type BridgeWithAddress = ReturnType['bridgeAssis export type TransactionContract = Awaited< ReturnType >[number] + +export type ITransaction = { + fromUser: string + toUser: string + amount: BigNumber + timestamp: BigNumber + fromChain: string + toChain: string + nonce: BigNumber + block: BigNumber +} + +export type ExtractedTransaction = { + fromUser: string + toUser: string + amount: string + timestamp: string + fromChain: string + toChain: string + nonce: string + block: string + confirmationsRequired: string +} diff --git a/backend-all/src/utils/constant.ts b/backend-all/src/utils/constant.ts index f6b691f..3480ed6 100644 --- a/backend-all/src/utils/constant.ts +++ b/backend-all/src/utils/constant.ts @@ -1,5 +1,6 @@ import { ChainId } from "@/gotbit-tools/node/types" import { IS_PROD } from '@/gotbit.config' +import {PublicKey} from '@solana/web3.js' export const REAL_CHAIN_IDS: ChainId[] = IS_PROD ? ['97', '421614', '42421', '84532'] @@ -19,6 +20,10 @@ export const eip712Transaction = { ], } + +export const SOLANABRIDGE_TOKENS= { + '5Ff1K9UAT3RWqdZ24qcF3w3UNTvXWkfaqirQgWzgdsYb': "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU" +} export const BRIDGEASSISTS = { "1": [ diff --git a/backend-all/src/utils/helpers.ts b/backend-all/src/utils/helpers.ts index 98fd2be..535339d 100644 --- a/backend-all/src/utils/helpers.ts +++ b/backend-all/src/utils/helpers.ts @@ -12,9 +12,10 @@ import { polygon_mainnet_rpc, relayerIndex, } from './env-var' -import { providers } from 'ethers' +import { BigNumber, providers } from 'ethers' import { universalRpc } from '@/gotbit-tools/node/rpc' import { getChainName, getChainTag } from '@/gotbit-tools/node' +import { getConfirmationsRequired } from './solana/helpers' export async function getActiveRpc(rpcList: string[], timeoutMs: number = 5000) { /** @@ -121,3 +122,8 @@ export async function _getProvider(chainId: ChainId) { if (!rpc) throw new Error(`Relayer ${relayerIndex} Rpc error. Please try again later`) return new providers.JsonRpcProvider(rpc) } + +export async function hasPassedConfirmationEvm(provider: providers.JsonRpcProvider, fromChain: ChainId, block: BigNumber) { + const blockNumber = await provider.getBlockNumber() + return BigNumber.from(blockNumber).gt(block.add(getConfirmationsRequired(fromChain))) +} diff --git a/backend-all/src/utils/solana/helpers.ts b/backend-all/src/utils/solana/helpers.ts new file mode 100644 index 0000000..d4f039b --- /dev/null +++ b/backend-all/src/utils/solana/helpers.ts @@ -0,0 +1,513 @@ +import { + ASSOCIATED_TOKEN_PROGRAM_ID, + createAssociatedTokenAccountInstruction, + TOKEN_PROGRAM_ID, + TokenOwnerOffCurveError, +} from '@solana/spl-token' +import { + clusterApiUrl, + Connection, + Keypair, + PublicKey, + sendAndConfirmTransaction, + Transaction, +} from '@solana/web3.js' +import { AnchorProvider, BN, Program } from '@coral-xyz/anchor' +import NodeWallet from '@coral-xyz/anchor/dist/cjs/nodewallet' +import IDL from './idl/assetchain_bridge_solana.json' +import { AssetchainBridgeSolana } from './types/assetchain_bridge_solana' +import { ExtractedTransaction, ITransaction } from '@/types' +import { ChainId } from '@/gotbit-tools/node/types' +import bs58 from 'bs58' +import CONFIRMATION from '../../confirmations.json' +import { BigNumber } from 'ethers' +import { SOLANABRIDGE_TOKENS } from '../constant' +import { config } from 'dotenv' + +config() + +// console.log(process.env.SOLANA_KEY!, 'sksk') + +const isMain = process.env.SOLANA_MAINNET === 'true' + +const secretKey = bs58.decode(process.env.SOLANA_KEY!) + +// export const CURRENT_CHAIN_BUFFER = () => +// Buffer.from(CURRENT_CHAIN().padEnd(32, "\0"), "ascii"); + +/** + * Get the Solana workspace. + * + * @returns workspace The Solana workspace. + * @returns workspace.payer The creator of the bridge instance. + * @returns workspace.owner The creator of the bridge instance. + * @returns workspace.tokenMint The Solana token address. + * @returns workspace.connection The Solana connection. + * @returns workspace.provider The Solana provider. + * @returns workspace.program The Solana program. + */ +export const solanaWorkspace = (bridgeAssist: string) => { + const owner = Keypair.fromSecretKey(secretKey) + + const network = clusterApiUrl(isMain ? 'mainnet-beta' : 'devnet') + const connection = new Connection(network, 'confirmed') + const provider = new AnchorProvider(connection, new NodeWallet(owner), { + preflightCommitment: 'confirmed', + }) + const program = new Program(IDL, provider) + const tokenMint = (SOLANABRIDGE_TOKENS as any)[bridgeAssist] + if (!tokenMint) throw new Error(`Token mint not initialized`) + + return { + payer: owner, + owner, + tokenMint: new PublicKey(tokenMint), + connection, + provider, + program, + } +} + +/** + * Async version of getAssociatedTokenAddressSync + * For backwards compatibility + * + * @param mint Token mint account + * @param owner Owner of the new account + * @param allowOwnerOffCurve Allow the owner account to be a PDA (Program Derived Address) + * @param programId SPL Token program account + * @param associatedTokenProgramId SPL Associated Token program account + * + * @return Promise containing the address of the associated token account + */ +export async function getAssociatedTokenAddress( + mint: PublicKey, + owner: PublicKey, + allowOwnerOffCurve = false, + programId = TOKEN_PROGRAM_ID, + associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID +): Promise { + if (!allowOwnerOffCurve && !PublicKey.isOnCurve(owner.toBuffer())) + throw new TokenOwnerOffCurveError() + + const [address] = await PublicKey.findProgramAddress( + [owner.toBuffer(), programId.toBuffer(), mint.toBuffer()], + associatedTokenProgramId + ) + return address +} + +export async function getOrCreateAssociatedTokenAccount( + connection: Connection, + mint: PublicKey, + owner: PublicKey, + payer: Keypair // payer pays the account creation fee +): Promise { + // 1. Derive ATA address + const ata = await getAssociatedTokenAddress(mint, owner); + + // 2. Check if ATA account exists + const accountInfo = await connection.getAccountInfo(ata); + if (accountInfo === null) { + // ATA does not exist; create it + const ix = createAssociatedTokenAccountInstruction( + payer.publicKey, // payer + ata, // ATA address to create + owner, // owner of ATA + mint // mint + ); + + const tx = new Transaction().add(ix); + + // Send transaction to create ATA + await sendAndConfirmTransaction(connection, tx, [payer], {commitment:'confirmed'}); + + console.log(`Created ATA: ${ata.toBase58()}`); + } else { + console.log(`ATA exists: ${ata.toBase58()}`); + } + + return ata; +} + +/** + * Converts a transaction to a common representation not dependent on anchor or ethers. Used to display transaction data + * and build the fulfill transaction on the frontend. + * + * @param tx The transaction to convert + * @returns extractedTx The converted transaction + */ +export const extractTransaction = (tx: ITransaction): ExtractedTransaction => { + return { + fromUser: tx.fromUser, + toUser: tx.toUser, + amount: tx.amount.toString(), + timestamp: tx.timestamp.toString(), + fromChain: tx.fromChain, + toChain: tx.toChain, + nonce: tx.nonce.toString(), + block: tx.block.toString(), + confirmationsRequired: getConfirmationsRequired(tx.fromChain) + '', + } +} + +export function getConfirmationsRequired(network: string) { + if (network.startsWith('evm.')) { + const chainId = network.slice(4) as ChainId + return CONFIRMATION[chainId!] + } else { + return CONFIRMATION.solana + } +} + +/** + * Get an instance-specific empty PDA used as a marker of the transaction with nonce `nonce` having been fulfilled on + * Solana. + * + * @param programId Solana program ID. + * @param bridgeOwner Creator of the bridge instance + * @param tokenMint Solana token address + * @param nonce Nonce of the transaction + * @param fromChain Source chain, e.g. "evm.1" for Ethereum. + * @returns account The instance-specific empty PDA used as a marker of the transaction with nonce `nonce` having been fulfilled on Solana + */ +const getEmptyAccount = ( + programId: PublicKey, + bridgeOwner: PublicKey, + tokenMint: PublicKey, + nonce: BN, + fromChain: string +) => { + return PublicKey.findProgramAddressSync( + [ + SOLANA_PROGRAM_VERSION().toBuffer('be', 8), + Buffer.from('fulfilled'), + bridgeOwner.toBuffer(), + tokenMint.toBuffer(), + nonce.toBuffer('be', 8), + CHAIN_TO_BUFFER(fromChain), + SOL_CHAIN_BUFFER(), + ], + programId + ) +} + +export async function isToSolanaTxFulfilled( + toBridgeAddress: string, + fromChainId: ChainId, + nonce: BigNumber +): Promise { + const { owner, tokenMint, program } = solanaWorkspace(toBridgeAddress) + + // const { bridgeAssist } = useContracts(undefined, fromChainId) + // const CURRENT_CHAIN = await safeRead(bridgeAssist.CURRENT_CHAIN(), 'INVALID') + // if (CURRENT_CHAIN == 'INVALID') return false + const CURRENT_CHAIN = 'evm.' + fromChainId + + const emptyAccount = getEmptyAccount( + program.programId, + owner.publicKey, + tokenMint, + new BN(nonce.toString()), + CURRENT_CHAIN + )[0] + + const emptyAccountInfo = await program.provider.connection.getAccountInfo(emptyAccount) + + return emptyAccountInfo !== null +} + +// const getBridgeAccount = ( +// name: string, +// programId: PublicKey, +// bridgeOwner: PublicKey, +// tokenMint: PublicKey +// ) => { +// return PublicKey.findProgramAddressSync( +// [ +// SOLANA_PROGRAM_VERSION().toBuffer("be", 8), +// Buffer.from(name), +// bridgeOwner.toBuffer(), +// tokenMint.toBuffer(), +// CURRENT_CHAIN_BUFFER(), +// ], +// programId +// ); +// }; + +/** + * Builds a Solana fulfill transaction and signs it with the key that created the bridge instance. + * + * @param tx The transaction to fulfill + * @param userTokenAccount The user's token account that will receive the funds + * @returns fulfillTx The fulfill transaction signed and serialized + */ +export const signSolana = async ( + toBridgeAddress: string, + tx: ExtractedTransaction, + userTokenAccount: PublicKey +) => { + const { owner, tokenMint, program, connection } = solanaWorkspace(toBridgeAddress) + const user = new PublicKey(tx.toUser) + console.log(user.toBase58(), 'toUser') + const bridgeTokenAccount = getBridgeAccount( + 'wallet', + program.programId, + owner.publicKey, + tokenMint + )[0] + console.log(bridgeTokenAccount.toBase58(), 'bridgeTokenAccount') + const bridgeParams = getBridgeAccount( + 'bridge_params', + program.programId, + owner.publicKey, + tokenMint + )[0] + console.log(bridgeParams.toBase58(), 'bridgeParams') + + const params = await program.account.bridgeParams.fetch(bridgeParams) + + // const { bridgeAssist } = useContracts(undefined, tx.fromChain.slice(4) as EthChainId) + // const CURRENT_CHAIN = await bridgeAssist.CURRENT_CHAIN() + const CURRENT_CHAIN = tx.fromChain + + const instruction = await (program.methods as any) + .fulfill( + new BN(tx.nonce), + new BN(tx.amount), + SOLANA_PROGRAM_VERSION(), + SOL_CHAIN_B32(), + CHAIN_TO_B32(CURRENT_CHAIN) + ) + .accounts({ + tokenMint, + userTokenAccount, + bridgeTokenAccount, + feeAccount: params.feeRecipient, + user, + owner: owner.publicKey, + bridgeParams, + emptyAccount: getEmptyAccount( + program.programId, + owner.publicKey, + tokenMint, + new BN(tx.nonce), + CURRENT_CHAIN + )[0], + fromChainData: getChainDataAccount( + program.programId, + owner.publicKey, + tokenMint, + CURRENT_CHAIN + )[0], + }) + .instruction() + + const solanaTx = new Transaction() + solanaTx.add(instruction) + solanaTx.feePayer = user + solanaTx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash + solanaTx.partialSign(owner) + + return solanaTx.serialize({ requireAllSignatures: false }) +} + +function parseBytes32String(bytes32Buffer: Buffer) { + // Find first null byte + const nullIndex = bytes32Buffer.indexOf(0) + if (nullIndex !== -1) { + return bytes32Buffer.slice(0, nullIndex).toString('utf8') + } + // If no null byte found, convert all + return bytes32Buffer.toString('utf8') +} + +export async function getSolanaSendTx( + owner: Keypair, + tokenMint: PublicKey, + program: Program, + user: PublicKey, + nonce: string, + fromChain: string +) { + const sendTxKey = getSendTxAccount( + program.programId, + owner.publicKey, + tokenMint, + user, + new BN(nonce) + )[0] + const sendTxAccount = await program.account.bridgeSendTx.fetch(sendTxKey) + + if (!sendTxAccount) throw new Error(`Transaction not found with nonce ${nonce}`) + + console.log(sendTxAccount.toChain.byte, 'ssk') + + const tx: ITransaction = { + fromUser: user.toString(), + toUser: '0x' + Buffer.from(sendTxAccount.to.byte).toString('hex').slice(0, 40), + amount: solanaBnToEthersBn(sendTxAccount.amount), + timestamp: solanaBnToEthersBn(sendTxAccount.timestamp), + fromChain: fromChain, + toChain: parseBytes32String(Buffer.from(sendTxAccount.toChain.byte)), + nonce: BigNumber.from(nonce), + block: solanaBnToEthersBn(sendTxAccount.block), + } + + return tx +} + +function solanaBnToEthersBn(bn: BN) { + return BigNumber.from(bn.toString()) +} +/** + * Gets a bridge instance-specific user-specific PDA. Used to get the `send_nonce` account that stores the user's nonce. + * + * @param name Name of the account, e.g. "send_nonce". + * @param programId Solana program ID. + * @param bridgeOwner Creator of the bridge instance + * @param tokenMint Solana token address + * @param user Solana address of the user + * @returns account The user-specific account + */ +export const getBridgeUserAccount = ( + name: string, + programId: PublicKey, + bridgeOwner: PublicKey, + tokenMint: PublicKey, + user: PublicKey +) => { + return PublicKey.findProgramAddressSync( + [ + SOLANA_PROGRAM_VERSION().toBuffer('be', 8), + Buffer.from(name), + bridgeOwner.toBuffer(), + tokenMint.toBuffer(), + user.toBuffer(), + SOL_CHAIN_BUFFER(), + ], + programId + ) +} + +/** + * Gets a bridge instance-specific PDA. + * + * @param name Name of the account, e.g. "bridge_params". + * @param programId Solana program ID. + * @param bridgeOwner Creator of the bridge instance + * @param tokenMint Solana token address + * @returns account The instance-specific PDA + */ +export const getBridgeAccount = ( + name: string, + programId: PublicKey, + bridgeOwner: PublicKey, + tokenMint: PublicKey +) => { + return PublicKey.findProgramAddressSync( + [ + SOLANA_PROGRAM_VERSION().toBuffer('be', 8), + Buffer.from(name), + bridgeOwner.toBuffer(), + tokenMint.toBuffer(), + SOL_CHAIN_BUFFER(), + ], + programId + ) +} + +/** + * Gets a bridge-instance specific PDA storing data for a destination chain. + * If the account does not exist, the chain is not supported. + * + * @param programId Solana program ID. + * @param bridgeOwner Creator of the bridge instance + * @param tokenMint Solana token address + * @param toChain Destination chain, e.g. "evm.1" for Ethereum. + * @returns account The instance-specific PDA storing data for a destination chain + */ +export const getChainDataAccount = ( + programId: PublicKey, + bridgeOwner: PublicKey, + tokenMint: PublicKey, + toChain: string +) => { + return PublicKey.findProgramAddressSync( + [ + SOLANA_PROGRAM_VERSION().toBuffer('be', 8), + Buffer.from('chain_data'), + bridgeOwner.toBuffer(), + tokenMint.toBuffer(), + SOL_CHAIN_BUFFER(), + CHAIN_TO_BUFFER(toChain), + ], + programId + ) +} + +export const SOLANA_PROGRAM_VERSION: () => BN = () => new BN(1) +export const SOL_CHAIN = () => (isMain ? `sol.mainnet` : `sol.devnet`) + +/** @returns chain The identifier of the Solana chain used as a null-terminated string encoded as a 32 byte long array of bytes (ASCII character codes). */ +export const SOL_CHAIN_BUFFER = () => Buffer.from(SOL_CHAIN().padEnd(32, '\0'), 'ascii') +export const CHAIN_TO_BUFFER = (chain: string) => + Buffer.from(chain.padEnd(32, '\0'), 'ascii') + +/** + * @returns chain An object wrapping the result of SOL_CHAIN_BUFFER(). + * @returns chain.byte Solana chain used as a null-terminated string encoded as a 32 byte long array of bytes (ASCII character codes). + */ +export const SOL_CHAIN_B32 = () => ({ + byte: Array.from(SOL_CHAIN_BUFFER()), +}) + +/** + * Converts a string (chain id) for passing it to the blockchain. + * + * @param chain The string to convert, e.g. "evm.1" for Ethereum. + * @returns chain An object wrapping the result of CHAIN_TO_BUFFER(). + * @returns chain.byte A null-terminated padded converted string encoded as a 32 byte long array of bytes (ASCII character codes). + */ +export const CHAIN_TO_B32 = (chain: string) => ({ + byte: Array.from(CHAIN_TO_BUFFER(chain)), +}) + +/** + * Get an instance-specific PDA storing data for a bridge transaction sent from Solana. + * + * @param programId Solana program ID. + * @param bridgeOwner Creator of the bridge instance + * @param tokenMint Solana token address + * @param user Solana address of the user + * @param nonce Nonce of the transaction + * @returns account The instance-specific PDA storing data for a bridge transaction sent from Solana + */ +export const getSendTxAccount = ( + programId: PublicKey, + bridgeOwner: PublicKey, + tokenMint: PublicKey, + user: PublicKey, + nonce: BN +) => { + return PublicKey.findProgramAddressSync( + [ + SOLANA_PROGRAM_VERSION().toBuffer('be', 8), + Buffer.from('send_tx'), + bridgeOwner.toBuffer(), + tokenMint.toBuffer(), + user.toBuffer(), + nonce.toBuffer('be', 8), + SOL_CHAIN_BUFFER(), + ], + programId + ) +} + +export async function hasPassedConfirmationSolana( + connection: Connection, + tx: ITransaction +) { + const block = await connection.getSlot() + return BigNumber.from(block).gt(tx.block.add(getConfirmationsRequired(tx.fromChain))) +} diff --git a/backend-all/src/utils/solana/idl/assetchain_bridge_solana.json b/backend-all/src/utils/solana/idl/assetchain_bridge_solana.json new file mode 100644 index 0000000..cc61228 --- /dev/null +++ b/backend-all/src/utils/solana/idl/assetchain_bridge_solana.json @@ -0,0 +1,1275 @@ +{ + "address": "5Ff1K9UAT3RWqdZ24qcF3w3UNTvXWkfaqirQgWzgdsYb", + "metadata": { + "name": "assetchain_bridge_solana", + "version": "0.1.0", + "spec": "0.1.0", + "description": "Created with Anchor" + }, + "instructions": [ + { + "name": "fulfill", + "discriminator": [ + 143, + 2, + 52, + 206, + 174, + 164, + 247, + 72 + ], + "accounts": [ + { + "name": "token_mint" + }, + { + "name": "empty_account", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "_version" + }, + { + "kind": "const", + "value": [ + 102, + 117, + 108, + 102, + 105, + 108, + 108, + 101, + 100 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "account", + "path": "token_mint" + }, + { + "kind": "arg", + "path": "_nonce" + }, + { + "kind": "arg", + "path": "_from_chain.byte" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "user_token_account", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "account", + "path": "user" + }, + { + "kind": "const", + "value": [ + 6, + 221, + 246, + 225, + 215, + 101, + 161, + 147, + 217, + 203, + 225, + 70, + 206, + 235, + 121, + 172, + 28, + 180, + 133, + 237, + 95, + 91, + 55, + 145, + 58, + 140, + 245, + 133, + 126, + 255, + 0, + 169 + ] + }, + { + "kind": "account", + "path": "token_mint" + } + ], + "program": { + "kind": "const", + "value": [ + 140, + 151, + 37, + 143, + 78, + 36, + 137, + 241, + 187, + 61, + 16, + 41, + 20, + 142, + 13, + 131, + 11, + 90, + 19, + 153, + 218, + 255, + 16, + 132, + 4, + 142, + 123, + 216, + 219, + 233, + 248, + 89 + ] + } + } + }, + { + "name": "bridge_token_account", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "_version" + }, + { + "kind": "const", + "value": [ + 119, + 97, + 108, + 108, + 101, + 116 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "account", + "path": "token_mint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "fee_account", + "writable": true + }, + { + "name": "bridge_params", + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "_version" + }, + { + "kind": "const", + "value": [ + 98, + 114, + 105, + 100, + 103, + 101, + 95, + 112, + 97, + 114, + 97, + 109, + 115 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "account", + "path": "token_mint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "from_chain_data", + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "_version" + }, + { + "kind": "const", + "value": [ + 99, + 104, + 97, + 105, + 110, + 95, + 100, + 97, + 116, + 97 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "account", + "path": "token_mint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + }, + { + "kind": "arg", + "path": "_from_chain.byte" + } + ] + } + }, + { + "name": "user", + "writable": true, + "signer": true + }, + { + "name": "owner", + "signer": true + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + } + ], + "args": [ + { + "name": "_nonce", + "type": "u64" + }, + { + "name": "amount", + "type": "u64" + }, + { + "name": "version", + "type": "u64" + }, + { + "name": "current_chain", + "type": { + "defined": { + "name": "Bytes32" + } + } + }, + { + "name": "_from_chain", + "type": { + "defined": { + "name": "Bytes32" + } + } + } + ] + }, + { + "name": "initialize", + "discriminator": [ + 175, + 175, + 109, + 31, + 13, + 152, + 155, + 237 + ], + "accounts": [ + { + "name": "token_mint" + }, + { + "name": "bridge_token_account", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "_version" + }, + { + "kind": "const", + "value": [ + 119, + 97, + 108, + 108, + 101, + 116 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "account", + "path": "token_mint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "owner", + "writable": true, + "signer": true + }, + { + "name": "fee_account", + "writable": true + }, + { + "name": "bridge_params", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "_version" + }, + { + "kind": "const", + "value": [ + 98, + 114, + 105, + 100, + 103, + 101, + 95, + 112, + 97, + 114, + 97, + 109, + 115 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "account", + "path": "token_mint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + } + ], + "args": [ + { + "name": "fee_send", + "type": "u16" + }, + { + "name": "fee_fulfill", + "type": "u16" + }, + { + "name": "limit_send", + "type": "u64" + }, + { + "name": "paused", + "type": "bool" + }, + { + "name": "_version", + "type": "u64" + }, + { + "name": "_current_chain", + "type": { + "defined": { + "name": "Bytes32" + } + } + } + ] + }, + { + "name": "send", + "discriminator": [ + 102, + 251, + 20, + 187, + 65, + 75, + 12, + 69 + ], + "accounts": [ + { + "name": "send_nonce", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "_version" + }, + { + "kind": "const", + "value": [ + 115, + 101, + 110, + 100, + 95, + 110, + 111, + 110, + 99, + 101 + ] + }, + { + "kind": "arg", + "path": "_owner" + }, + { + "kind": "arg", + "path": "_token_mint" + }, + { + "kind": "account", + "path": "user" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "send_tx", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "_version" + }, + { + "kind": "const", + "value": [ + 115, + 101, + 110, + 100, + 95, + 116, + 120 + ] + }, + { + "kind": "arg", + "path": "_owner" + }, + { + "kind": "arg", + "path": "_token_mint" + }, + { + "kind": "account", + "path": "user" + }, + { + "kind": "account", + "path": "send_nonce.nonce", + "account": "UserNonce" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "user_token_account", + "writable": true + }, + { + "name": "bridge_token_account", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "_version" + }, + { + "kind": "const", + "value": [ + 119, + 97, + 108, + 108, + 101, + 116 + ] + }, + { + "kind": "arg", + "path": "_owner" + }, + { + "kind": "arg", + "path": "_token_mint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "fee_account", + "writable": true + }, + { + "name": "bridge_params", + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "_version" + }, + { + "kind": "const", + "value": [ + 98, + 114, + 105, + 100, + 103, + 101, + 95, + 112, + 97, + 114, + 97, + 109, + 115 + ] + }, + { + "kind": "arg", + "path": "_owner" + }, + { + "kind": "arg", + "path": "_token_mint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "to_chain_data", + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "_version" + }, + { + "kind": "const", + "value": [ + 99, + 104, + 97, + 105, + 110, + 95, + 100, + 97, + 116, + 97 + ] + }, + { + "kind": "arg", + "path": "_owner" + }, + { + "kind": "arg", + "path": "_token_mint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + }, + { + "kind": "arg", + "path": "to_chain.byte" + } + ] + } + }, + { + "name": "user", + "writable": true, + "signer": true + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + } + ], + "args": [ + { + "name": "_owner", + "type": "pubkey" + }, + { + "name": "_token_mint", + "type": "pubkey" + }, + { + "name": "amount", + "type": "u64" + }, + { + "name": "to", + "type": { + "defined": { + "name": "Bytes32" + } + } + }, + { + "name": "_version", + "type": "u64" + }, + { + "name": "to_chain", + "type": { + "defined": { + "name": "Bytes32" + } + } + }, + { + "name": "_current_chain", + "type": { + "defined": { + "name": "Bytes32" + } + } + } + ] + }, + { + "name": "set_chain_data", + "discriminator": [ + 214, + 54, + 247, + 40, + 78, + 208, + 151, + 153 + ], + "accounts": [ + { + "name": "owner", + "writable": true, + "signer": true + }, + { + "name": "chain_data", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "_version" + }, + { + "kind": "const", + "value": [ + 99, + 104, + 97, + 105, + 110, + 95, + 100, + 97, + 116, + 97 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "arg", + "path": "_token_mint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + }, + { + "kind": "arg", + "path": "_chain.byte" + } + ] + } + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "_token_mint", + "type": "pubkey" + }, + { + "name": "enabled", + "type": "bool" + }, + { + "name": "exchange_rate_from", + "type": "u64" + }, + { + "name": "_version", + "type": "u64" + }, + { + "name": "_current_chain", + "type": { + "defined": { + "name": "Bytes32" + } + } + }, + { + "name": "_chain", + "type": { + "defined": { + "name": "Bytes32" + } + } + } + ] + }, + { + "name": "set_params", + "discriminator": [ + 27, + 234, + 178, + 52, + 147, + 2, + 187, + 141 + ], + "accounts": [ + { + "name": "owner", + "writable": true, + "signer": true + }, + { + "name": "bridge_params", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "_version" + }, + { + "kind": "const", + "value": [ + 98, + 114, + 105, + 100, + 103, + 101, + 95, + 112, + 97, + 114, + 97, + 109, + 115 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "arg", + "path": "_token_mint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "fee_account", + "writable": true + } + ], + "args": [ + { + "name": "_token_mint", + "type": "pubkey" + }, + { + "name": "fee_send", + "type": "u16" + }, + { + "name": "fee_fulfill", + "type": "u16" + }, + { + "name": "limit_send", + "type": "u64" + }, + { + "name": "paused", + "type": "bool" + }, + { + "name": "_version", + "type": "u64" + }, + { + "name": "_current_chain", + "type": { + "defined": { + "name": "Bytes32" + } + } + } + ] + }, + { + "name": "withdraw", + "discriminator": [ + 183, + 18, + 70, + 156, + 148, + 109, + 161, + 34 + ], + "accounts": [ + { + "name": "token_mint" + }, + { + "name": "withdraw_token_account", + "writable": true + }, + { + "name": "bridge_token_account", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "_version" + }, + { + "kind": "const", + "value": [ + 119, + 97, + 108, + 108, + 101, + 116 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "account", + "path": "token_mint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "owner", + "signer": true + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + } + ], + "args": [ + { + "name": "version", + "type": "u64" + }, + { + "name": "current_chain", + "type": { + "defined": { + "name": "Bytes32" + } + } + } + ] + } + ], + "accounts": [ + { + "name": "BridgeParams", + "discriminator": [ + 249, + 32, + 241, + 181, + 92, + 58, + 96, + 253 + ] + }, + { + "name": "BridgeSendTx", + "discriminator": [ + 29, + 194, + 22, + 87, + 127, + 246, + 127, + 151 + ] + }, + { + "name": "ChainData", + "discriminator": [ + 70, + 133, + 31, + 188, + 8, + 245, + 216, + 203 + ] + }, + { + "name": "EmptyAccount", + "discriminator": [ + 174, + 156, + 186, + 113, + 230, + 158, + 33, + 215 + ] + }, + { + "name": "UserNonce", + "discriminator": [ + 235, + 133, + 1, + 243, + 18, + 135, + 88, + 224 + ] + } + ], + "errors": [ + { + "code": 6000, + "name": "SendFeeTooHigh" + }, + { + "code": 6001, + "name": "FulfillFeeTooHigh" + }, + { + "code": 6002, + "name": "ExchangeRateZero" + }, + { + "code": 6003, + "name": "BridgePaused" + }, + { + "code": 6004, + "name": "ChainDisabled" + }, + { + "code": 6005, + "name": "AmountTooLow" + }, + { + "code": 6006, + "name": "WithdrawZero" + }, + { + "code": 6007, + "name": "SendLimitExceeded" + }, + { + "code": 6008, + "name": "AmountUneven" + } + ], + "types": [ + { + "name": "BridgeParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "fee_send", + "type": "u16" + }, + { + "name": "fee_fulfill", + "type": "u16" + }, + { + "name": "limit_send", + "type": "u64" + }, + { + "name": "fee_recipient", + "type": "pubkey" + }, + { + "name": "paused", + "type": "bool" + } + ] + } + }, + { + "name": "BridgeSendTx", + "type": { + "kind": "struct", + "fields": [ + { + "name": "initiator", + "type": "pubkey" + }, + { + "name": "amount", + "type": "u64" + }, + { + "name": "to", + "type": { + "defined": { + "name": "Bytes32" + } + } + }, + { + "name": "nonce", + "type": "u64" + }, + { + "name": "timestamp", + "type": "i64" + }, + { + "name": "to_chain", + "type": { + "defined": { + "name": "Bytes32" + } + } + }, + { + "name": "block", + "type": "u64" + } + ] + } + }, + { + "name": "Bytes32", + "type": { + "kind": "struct", + "fields": [ + { + "name": "byte", + "type": { + "array": [ + "u8", + 32 + ] + } + } + ] + } + }, + { + "name": "ChainData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "enabled", + "type": "bool" + }, + { + "name": "exchange_rate_from", + "type": "u64" + } + ] + } + }, + { + "name": "EmptyAccount", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "UserNonce", + "type": { + "kind": "struct", + "fields": [ + { + "name": "nonce", + "type": "u64" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/backend-all/src/utils/solana/types/assetchain_bridge_solana.ts b/backend-all/src/utils/solana/types/assetchain_bridge_solana.ts new file mode 100644 index 0000000..2e8cf44 --- /dev/null +++ b/backend-all/src/utils/solana/types/assetchain_bridge_solana.ts @@ -0,0 +1,1281 @@ +/** + * Program IDL in camelCase format in order to be used in JS/TS. + * + * Note that this is only a type helper and is not the actual IDL. The original + * IDL can be found at `target/idl/assetchain_bridge_solana.json`. + */ +export type AssetchainBridgeSolana = { + "address": "5Ff1K9UAT3RWqdZ24qcF3w3UNTvXWkfaqirQgWzgdsYb", + "metadata": { + "name": "assetchainBridgeSolana", + "version": "0.1.0", + "spec": "0.1.0", + "description": "Created with Anchor" + }, + "instructions": [ + { + "name": "fulfill", + "discriminator": [ + 143, + 2, + 52, + 206, + 174, + 164, + 247, + 72 + ], + "accounts": [ + { + "name": "tokenMint" + }, + { + "name": "emptyAccount", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "version" + }, + { + "kind": "const", + "value": [ + 102, + 117, + 108, + 102, + 105, + 108, + 108, + 101, + 100 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "account", + "path": "tokenMint" + }, + { + "kind": "arg", + "path": "nonce" + }, + { + "kind": "arg", + "path": "_from_chain.byte" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "userTokenAccount", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "account", + "path": "user" + }, + { + "kind": "const", + "value": [ + 6, + 221, + 246, + 225, + 215, + 101, + 161, + 147, + 217, + 203, + 225, + 70, + 206, + 235, + 121, + 172, + 28, + 180, + 133, + 237, + 95, + 91, + 55, + 145, + 58, + 140, + 245, + 133, + 126, + 255, + 0, + 169 + ] + }, + { + "kind": "account", + "path": "tokenMint" + } + ], + "program": { + "kind": "const", + "value": [ + 140, + 151, + 37, + 143, + 78, + 36, + 137, + 241, + 187, + 61, + 16, + 41, + 20, + 142, + 13, + 131, + 11, + 90, + 19, + 153, + 218, + 255, + 16, + 132, + 4, + 142, + 123, + 216, + 219, + 233, + 248, + 89 + ] + } + } + }, + { + "name": "bridgeTokenAccount", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "version" + }, + { + "kind": "const", + "value": [ + 119, + 97, + 108, + 108, + 101, + 116 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "account", + "path": "tokenMint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "feeAccount", + "writable": true + }, + { + "name": "bridgeParams", + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "version" + }, + { + "kind": "const", + "value": [ + 98, + 114, + 105, + 100, + 103, + 101, + 95, + 112, + 97, + 114, + 97, + 109, + 115 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "account", + "path": "tokenMint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "fromChainData", + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "version" + }, + { + "kind": "const", + "value": [ + 99, + 104, + 97, + 105, + 110, + 95, + 100, + 97, + 116, + 97 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "account", + "path": "tokenMint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + }, + { + "kind": "arg", + "path": "_from_chain.byte" + } + ] + } + }, + { + "name": "user", + "writable": true, + "signer": true + }, + { + "name": "owner", + "signer": true + }, + { + "name": "systemProgram", + "address": "11111111111111111111111111111111" + }, + { + "name": "tokenProgram", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "associatedTokenProgram", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + } + ], + "args": [ + { + "name": "nonce", + "type": "u64" + }, + { + "name": "amount", + "type": "u64" + }, + { + "name": "version", + "type": "u64" + }, + { + "name": "currentChain", + "type": { + "defined": { + "name": "bytes32" + } + } + }, + { + "name": "fromChain", + "type": { + "defined": { + "name": "bytes32" + } + } + } + ] + }, + { + "name": "initialize", + "discriminator": [ + 175, + 175, + 109, + 31, + 13, + 152, + 155, + 237 + ], + "accounts": [ + { + "name": "tokenMint" + }, + { + "name": "bridgeTokenAccount", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "version" + }, + { + "kind": "const", + "value": [ + 119, + 97, + 108, + 108, + 101, + 116 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "account", + "path": "tokenMint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "owner", + "writable": true, + "signer": true + }, + { + "name": "feeAccount", + "writable": true + }, + { + "name": "bridgeParams", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "version" + }, + { + "kind": "const", + "value": [ + 98, + 114, + 105, + 100, + 103, + 101, + 95, + 112, + 97, + 114, + 97, + 109, + 115 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "account", + "path": "tokenMint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "systemProgram", + "address": "11111111111111111111111111111111" + }, + { + "name": "tokenProgram", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + } + ], + "args": [ + { + "name": "feeSend", + "type": "u16" + }, + { + "name": "feeFulfill", + "type": "u16" + }, + { + "name": "limitSend", + "type": "u64" + }, + { + "name": "paused", + "type": "bool" + }, + { + "name": "version", + "type": "u64" + }, + { + "name": "currentChain", + "type": { + "defined": { + "name": "bytes32" + } + } + } + ] + }, + { + "name": "send", + "discriminator": [ + 102, + 251, + 20, + 187, + 65, + 75, + 12, + 69 + ], + "accounts": [ + { + "name": "sendNonce", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "version" + }, + { + "kind": "const", + "value": [ + 115, + 101, + 110, + 100, + 95, + 110, + 111, + 110, + 99, + 101 + ] + }, + { + "kind": "arg", + "path": "owner" + }, + { + "kind": "arg", + "path": "tokenMint" + }, + { + "kind": "account", + "path": "user" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "sendTx", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "version" + }, + { + "kind": "const", + "value": [ + 115, + 101, + 110, + 100, + 95, + 116, + 120 + ] + }, + { + "kind": "arg", + "path": "owner" + }, + { + "kind": "arg", + "path": "tokenMint" + }, + { + "kind": "account", + "path": "user" + }, + { + "kind": "account", + "path": "send_nonce.nonce", + "account": "userNonce" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "userTokenAccount", + "writable": true + }, + { + "name": "bridgeTokenAccount", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "version" + }, + { + "kind": "const", + "value": [ + 119, + 97, + 108, + 108, + 101, + 116 + ] + }, + { + "kind": "arg", + "path": "owner" + }, + { + "kind": "arg", + "path": "tokenMint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "feeAccount", + "writable": true + }, + { + "name": "bridgeParams", + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "version" + }, + { + "kind": "const", + "value": [ + 98, + 114, + 105, + 100, + 103, + 101, + 95, + 112, + 97, + 114, + 97, + 109, + 115 + ] + }, + { + "kind": "arg", + "path": "owner" + }, + { + "kind": "arg", + "path": "tokenMint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "toChainData", + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "version" + }, + { + "kind": "const", + "value": [ + 99, + 104, + 97, + 105, + 110, + 95, + 100, + 97, + 116, + 97 + ] + }, + { + "kind": "arg", + "path": "owner" + }, + { + "kind": "arg", + "path": "tokenMint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + }, + { + "kind": "arg", + "path": "to_chain.byte" + } + ] + } + }, + { + "name": "user", + "writable": true, + "signer": true + }, + { + "name": "systemProgram", + "address": "11111111111111111111111111111111" + }, + { + "name": "tokenProgram", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + } + ], + "args": [ + { + "name": "owner", + "type": "pubkey" + }, + { + "name": "tokenMint", + "type": "pubkey" + }, + { + "name": "amount", + "type": "u64" + }, + { + "name": "to", + "type": { + "defined": { + "name": "bytes32" + } + } + }, + { + "name": "version", + "type": "u64" + }, + { + "name": "toChain", + "type": { + "defined": { + "name": "bytes32" + } + } + }, + { + "name": "currentChain", + "type": { + "defined": { + "name": "bytes32" + } + } + } + ] + }, + { + "name": "setChainData", + "discriminator": [ + 214, + 54, + 247, + 40, + 78, + 208, + 151, + 153 + ], + "accounts": [ + { + "name": "owner", + "writable": true, + "signer": true + }, + { + "name": "chainData", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "version" + }, + { + "kind": "const", + "value": [ + 99, + 104, + 97, + 105, + 110, + 95, + 100, + 97, + 116, + 97 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "arg", + "path": "tokenMint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + }, + { + "kind": "arg", + "path": "_chain.byte" + } + ] + } + }, + { + "name": "systemProgram", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "tokenMint", + "type": "pubkey" + }, + { + "name": "enabled", + "type": "bool" + }, + { + "name": "exchangeRateFrom", + "type": "u64" + }, + { + "name": "version", + "type": "u64" + }, + { + "name": "currentChain", + "type": { + "defined": { + "name": "bytes32" + } + } + }, + { + "name": "chain", + "type": { + "defined": { + "name": "bytes32" + } + } + } + ] + }, + { + "name": "setParams", + "discriminator": [ + 27, + 234, + 178, + 52, + 147, + 2, + 187, + 141 + ], + "accounts": [ + { + "name": "owner", + "writable": true, + "signer": true + }, + { + "name": "bridgeParams", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "version" + }, + { + "kind": "const", + "value": [ + 98, + 114, + 105, + 100, + 103, + 101, + 95, + 112, + 97, + 114, + 97, + 109, + 115 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "arg", + "path": "tokenMint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "feeAccount", + "writable": true + } + ], + "args": [ + { + "name": "tokenMint", + "type": "pubkey" + }, + { + "name": "feeSend", + "type": "u16" + }, + { + "name": "feeFulfill", + "type": "u16" + }, + { + "name": "limitSend", + "type": "u64" + }, + { + "name": "paused", + "type": "bool" + }, + { + "name": "version", + "type": "u64" + }, + { + "name": "currentChain", + "type": { + "defined": { + "name": "bytes32" + } + } + } + ] + }, + { + "name": "withdraw", + "discriminator": [ + 183, + 18, + 70, + 156, + 148, + 109, + 161, + 34 + ], + "accounts": [ + { + "name": "tokenMint" + }, + { + "name": "withdrawTokenAccount", + "writable": true + }, + { + "name": "bridgeTokenAccount", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "arg", + "path": "version" + }, + { + "kind": "const", + "value": [ + 119, + 97, + 108, + 108, + 101, + 116 + ] + }, + { + "kind": "account", + "path": "owner" + }, + { + "kind": "account", + "path": "tokenMint" + }, + { + "kind": "arg", + "path": "_current_chain.byte" + } + ] + } + }, + { + "name": "owner", + "signer": true + }, + { + "name": "tokenProgram", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + } + ], + "args": [ + { + "name": "version", + "type": "u64" + }, + { + "name": "currentChain", + "type": { + "defined": { + "name": "bytes32" + } + } + } + ] + } + ], + "accounts": [ + { + "name": "bridgeParams", + "discriminator": [ + 249, + 32, + 241, + 181, + 92, + 58, + 96, + 253 + ] + }, + { + "name": "bridgeSendTx", + "discriminator": [ + 29, + 194, + 22, + 87, + 127, + 246, + 127, + 151 + ] + }, + { + "name": "chainData", + "discriminator": [ + 70, + 133, + 31, + 188, + 8, + 245, + 216, + 203 + ] + }, + { + "name": "emptyAccount", + "discriminator": [ + 174, + 156, + 186, + 113, + 230, + 158, + 33, + 215 + ] + }, + { + "name": "userNonce", + "discriminator": [ + 235, + 133, + 1, + 243, + 18, + 135, + 88, + 224 + ] + } + ], + "errors": [ + { + "code": 6000, + "name": "sendFeeTooHigh" + }, + { + "code": 6001, + "name": "fulfillFeeTooHigh" + }, + { + "code": 6002, + "name": "exchangeRateZero" + }, + { + "code": 6003, + "name": "bridgePaused" + }, + { + "code": 6004, + "name": "chainDisabled" + }, + { + "code": 6005, + "name": "amountTooLow" + }, + { + "code": 6006, + "name": "withdrawZero" + }, + { + "code": 6007, + "name": "sendLimitExceeded" + }, + { + "code": 6008, + "name": "amountUneven" + } + ], + "types": [ + { + "name": "bridgeParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "feeSend", + "type": "u16" + }, + { + "name": "feeFulfill", + "type": "u16" + }, + { + "name": "limitSend", + "type": "u64" + }, + { + "name": "feeRecipient", + "type": "pubkey" + }, + { + "name": "paused", + "type": "bool" + } + ] + } + }, + { + "name": "bridgeSendTx", + "type": { + "kind": "struct", + "fields": [ + { + "name": "initiator", + "type": "pubkey" + }, + { + "name": "amount", + "type": "u64" + }, + { + "name": "to", + "type": { + "defined": { + "name": "bytes32" + } + } + }, + { + "name": "nonce", + "type": "u64" + }, + { + "name": "timestamp", + "type": "i64" + }, + { + "name": "toChain", + "type": { + "defined": { + "name": "bytes32" + } + } + }, + { + "name": "block", + "type": "u64" + } + ] + } + }, + { + "name": "bytes32", + "type": { + "kind": "struct", + "fields": [ + { + "name": "byte", + "type": { + "array": [ + "u8", + 32 + ] + } + } + ] + } + }, + { + "name": "chainData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "enabled", + "type": "bool" + }, + { + "name": "exchangeRateFrom", + "type": "u64" + } + ] + } + }, + { + "name": "emptyAccount", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "userNonce", + "type": { + "kind": "struct", + "fields": [ + { + "name": "nonce", + "type": "u64" + } + ] + } + } + ] +}; diff --git a/backend-all/yarn.lock b/backend-all/yarn.lock index a111a65..510627f 100644 --- a/backend-all/yarn.lock +++ b/backend-all/yarn.lock @@ -267,6 +267,11 @@ dependencies: regenerator-runtime "^0.13.11" +"@babel/runtime@^7.25.0": + version "7.27.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.6.tgz#ec4070a04d76bae8ddbb10770ba55714a417b7c6" + integrity sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q== + "@babel/template@^7.20.7", "@babel/template@^7.21.9", "@babel/template@^7.3.3": version "7.21.9" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.21.9.tgz#bf8dad2859130ae46088a99c1f265394877446fb" @@ -306,6 +311,38 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@coral-xyz/anchor-errors@^0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@coral-xyz/anchor-errors/-/anchor-errors-0.31.1.tgz#d635cbac2533973ae6bfb5d3ba1de89ce5aece2d" + integrity sha512-NhNEku4F3zzUSBtrYz84FzYWm48+9OvmT1Hhnwr6GnPQry2dsEqH/ti/7ASjjpoFTWRnPXrjAIT1qM6Isop+LQ== + +"@coral-xyz/anchor@^0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.31.1.tgz#0fdeebf45a3cb2e47e8ebbb815ca98542152962c" + integrity sha512-QUqpoEK+gi2S6nlYc2atgT2r41TT3caWr/cPUEL8n8Md9437trZ68STknq897b82p5mW0XrTBNOzRbmIRJtfsA== + dependencies: + "@coral-xyz/anchor-errors" "^0.31.1" + "@coral-xyz/borsh" "^0.31.1" + "@noble/hashes" "^1.3.1" + "@solana/web3.js" "^1.69.0" + bn.js "^5.1.2" + bs58 "^4.0.1" + buffer-layout "^1.2.2" + camelcase "^6.3.0" + cross-fetch "^3.1.5" + eventemitter3 "^4.0.7" + pako "^2.0.3" + superstruct "^0.15.4" + toml "^3.0.0" + +"@coral-xyz/borsh@^0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.31.1.tgz#5328e1e0921b75d7f4a62dd3f61885a938bc7241" + integrity sha512-9N8AU9F0ubriKfNE3g1WF0/4dtlGXoBN/hd1PvbNBamBNwRgHxH4P+o3Zt7rSEloW1HUs6LfZEchlx9fW7POYw== + dependencies: + bn.js "^5.1.2" + buffer-layout "^1.2.0" + "@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" @@ -893,6 +930,18 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" +"@noble/curves@^1.4.2": + version "1.9.2" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.9.2.tgz#73388356ce733922396214a933ff7c95afcef911" + integrity sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g== + dependencies: + "@noble/hashes" "1.8.0" + +"@noble/hashes@1.8.0", "@noble/hashes@^1.3.1", "@noble/hashes@^1.4.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a" + integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== + "@sinclair/typebox@^0.25.16": version "0.25.24" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" @@ -912,6 +961,162 @@ dependencies: "@sinonjs/commons" "^3.0.0" +"@solana/buffer-layout-utils@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz#b45a6cab3293a2eb7597cceb474f229889d875ca" + integrity sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g== + dependencies: + "@solana/buffer-layout" "^4.0.0" + "@solana/web3.js" "^1.32.0" + bigint-buffer "^1.1.5" + bignumber.js "^9.0.1" + +"@solana/buffer-layout@^4.0.0", "@solana/buffer-layout@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15" + integrity sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA== + dependencies: + buffer "~6.0.3" + +"@solana/codecs-core@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz#1a2d76b9c7b9e7b7aeb3bd78be81c2ba21e3ce22" + integrity sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ== + dependencies: + "@solana/errors" "2.0.0-rc.1" + +"@solana/codecs-core@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@solana/codecs-core/-/codecs-core-2.1.1.tgz#5d09d7f35b0266789d7c1f9306c08051128a6a64" + integrity sha512-iPQW3UZ2Vi7QFBo2r9tw0NubtH8EdrhhmZulx6lC8V5a+qjaxovtM/q/UW2BTNpqqHLfO0tIcLyBLrNH4HTWPg== + dependencies: + "@solana/errors" "2.1.1" + +"@solana/codecs-data-structures@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@solana/codecs-data-structures/-/codecs-data-structures-2.0.0-rc.1.tgz#d47b2363d99fb3d643f5677c97d64a812982b888" + integrity sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog== + dependencies: + "@solana/codecs-core" "2.0.0-rc.1" + "@solana/codecs-numbers" "2.0.0-rc.1" + "@solana/errors" "2.0.0-rc.1" + +"@solana/codecs-numbers@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz#f34978ddf7ea4016af3aaed5f7577c1d9869a614" + integrity sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ== + dependencies: + "@solana/codecs-core" "2.0.0-rc.1" + "@solana/errors" "2.0.0-rc.1" + +"@solana/codecs-numbers@^2.1.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@solana/codecs-numbers/-/codecs-numbers-2.1.1.tgz#b7a69024e2397e236bbfb11b75ff4a077236b9d2" + integrity sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ== + dependencies: + "@solana/codecs-core" "2.1.1" + "@solana/errors" "2.1.1" + +"@solana/codecs-strings@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@solana/codecs-strings/-/codecs-strings-2.0.0-rc.1.tgz#e1d9167075b8c5b0b60849f8add69c0f24307018" + integrity sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g== + dependencies: + "@solana/codecs-core" "2.0.0-rc.1" + "@solana/codecs-numbers" "2.0.0-rc.1" + "@solana/errors" "2.0.0-rc.1" + +"@solana/codecs@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@solana/codecs/-/codecs-2.0.0-rc.1.tgz#146dc5db58bd3c28e04b4c805e6096c2d2a0a875" + integrity sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ== + dependencies: + "@solana/codecs-core" "2.0.0-rc.1" + "@solana/codecs-data-structures" "2.0.0-rc.1" + "@solana/codecs-numbers" "2.0.0-rc.1" + "@solana/codecs-strings" "2.0.0-rc.1" + "@solana/options" "2.0.0-rc.1" + +"@solana/errors@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@solana/errors/-/errors-2.0.0-rc.1.tgz#3882120886eab98a37a595b85f81558861b29d62" + integrity sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ== + dependencies: + chalk "^5.3.0" + commander "^12.1.0" + +"@solana/errors@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@solana/errors/-/errors-2.1.1.tgz#009ebf387b0c014a8fc60a59d65757fef942e4fd" + integrity sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw== + dependencies: + chalk "^5.4.1" + commander "^13.1.0" + +"@solana/options@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@solana/options/-/options-2.0.0-rc.1.tgz#06924ba316dc85791fc46726a51403144a85fc4d" + integrity sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA== + dependencies: + "@solana/codecs-core" "2.0.0-rc.1" + "@solana/codecs-data-structures" "2.0.0-rc.1" + "@solana/codecs-numbers" "2.0.0-rc.1" + "@solana/codecs-strings" "2.0.0-rc.1" + "@solana/errors" "2.0.0-rc.1" + +"@solana/spl-token-group@^0.0.7": + version "0.0.7" + resolved "https://registry.yarnpkg.com/@solana/spl-token-group/-/spl-token-group-0.0.7.tgz#83c00f0cd0bda33115468cd28b89d94f8ec1fee4" + integrity sha512-V1N/iX7Cr7H0uazWUT2uk27TMqlqedpXHRqqAbVO2gvmJyT0E0ummMEAVQeXZ05ZhQ/xF39DLSdBp90XebWEug== + dependencies: + "@solana/codecs" "2.0.0-rc.1" + +"@solana/spl-token-metadata@^0.1.6": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@solana/spl-token-metadata/-/spl-token-metadata-0.1.6.tgz#d240947aed6e7318d637238022a7b0981b32ae80" + integrity sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA== + dependencies: + "@solana/codecs" "2.0.0-rc.1" + +"@solana/spl-token@^0.4.13": + version "0.4.13" + resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.4.13.tgz#8f65c3c2b315e1a00a91b8d0f60922c6eb71de62" + integrity sha512-cite/pYWQZZVvLbg5lsodSovbetK/eA24gaR0eeUeMuBAMNrT8XFCwaygKy0N2WSg3gSyjjNpIeAGBAKZaY/1w== + dependencies: + "@solana/buffer-layout" "^4.0.0" + "@solana/buffer-layout-utils" "^0.2.0" + "@solana/spl-token-group" "^0.0.7" + "@solana/spl-token-metadata" "^0.1.6" + buffer "^6.0.3" + +"@solana/web3.js@^1.32.0", "@solana/web3.js@^1.69.0", "@solana/web3.js@^1.98.2": + version "1.98.2" + resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.98.2.tgz#45167a5cfb64436944bf4dc1e8be8482bd6d4c14" + integrity sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A== + dependencies: + "@babel/runtime" "^7.25.0" + "@noble/curves" "^1.4.2" + "@noble/hashes" "^1.4.0" + "@solana/buffer-layout" "^4.0.1" + "@solana/codecs-numbers" "^2.1.0" + agentkeepalive "^4.5.0" + bn.js "^5.2.1" + borsh "^0.7.0" + bs58 "^4.0.1" + buffer "6.0.3" + fast-stable-stringify "^1.0.0" + jayson "^4.1.1" + node-fetch "^2.7.0" + rpc-websockets "^9.0.2" + superstruct "^2.0.2" + +"@swc/helpers@^0.5.11": + version "0.5.17" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.17.tgz#5a7be95ac0f0bf186e7e6e890e7a6f6cda6ce971" + integrity sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A== + dependencies: + tslib "^2.8.0" + "@types/babel__core@^7.1.14": version "7.20.1" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.1.tgz#916ecea274b0c776fec721e333e55762d3a9614b" @@ -965,6 +1170,13 @@ dependencies: "@types/node" "*" +"@types/connect@^3.4.33": + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== + dependencies: + "@types/node" "*" + "@types/cookiejar@*": version "2.1.2" resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.2.tgz#66ad9331f63fe8a3d3d9d8c6e3906dd10f6446e8" @@ -1058,6 +1270,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.2.5.tgz#26d295f3570323b2837d322180dfbf1ba156fefb" integrity sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ== +"@types/node@^12.12.54": + version "12.20.55" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== + "@types/node@^17.0.31": version "17.0.45" resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" @@ -1114,6 +1331,25 @@ dependencies: "@types/superagent" "*" +"@types/uuid@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + +"@types/ws@^7.4.4": + version "7.4.7" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== + dependencies: + "@types/node" "*" + +"@types/ws@^8.2.2": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" + integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "21.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" @@ -1139,6 +1375,13 @@ aes-js@3.0.0: resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== +agentkeepalive@^4.5.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz#35f73e94b3f40bf65f105219c623ad19c136ea6a" + integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ== + dependencies: + humanize-ms "^1.2.1" + ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" @@ -1288,6 +1531,23 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base-x@^3.0.2: + version "3.0.11" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.11.tgz#40d80e2a1aeacba29792ccc6c5354806421287ff" + integrity sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA== + dependencies: + safe-buffer "^5.0.1" + +base-x@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-5.0.1.tgz#16bf35254be1df8aca15e36b7c1dda74b2aa6b03" + integrity sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg== + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + basic-auth@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" @@ -1300,16 +1560,40 @@ bech32@1.1.4: resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== +bigint-buffer@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/bigint-buffer/-/bigint-buffer-1.1.5.tgz#d038f31c8e4534c1f8d0015209bf34b4fa6dd442" + integrity sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA== + dependencies: + bindings "^1.3.0" + +bignumber.js@^9.0.1: + version "9.3.0" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.3.0.tgz#bdba7e2a4c1a2eba08290e8dcad4f36393c92acd" + integrity sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +bindings@^1.3.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== +bn.js@^5.1.2, bn.js@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.2.tgz#82c09f9ebbb17107cd72cb7fd39bd1f9d0aaa566" + integrity sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw== + bn.js@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" @@ -1351,6 +1635,15 @@ body-parser@^1.20.0: type-is "~1.6.18" unpipe "1.0.0" +borsh@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a" + integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA== + dependencies: + bn.js "^5.2.0" + bs58 "^4.0.0" + text-encoding-utf-8 "^1.0.2" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1400,6 +1693,20 @@ bs-logger@0.x: dependencies: fast-json-stable-stringify "2.x" +bs58@^4.0.0, bs58@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== + dependencies: + base-x "^3.0.2" + +bs58@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-6.0.0.tgz#a2cda0130558535dd281a2f8697df79caaf425d8" + integrity sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw== + dependencies: + base-x "^5.0.0" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -1412,6 +1719,26 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer-layout@^1.2.0, buffer-layout@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/buffer-layout/-/buffer-layout-1.2.2.tgz#b9814e7c7235783085f9ca4966a0cfff112259d5" + integrity sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA== + +buffer@6.0.3, buffer@^6.0.3, buffer@~6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +bufferutil@^4.0.1: + version "4.0.9" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.9.tgz#6e81739ad48a95cad45a279588e13e95e24a800a" + integrity sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw== + dependencies: + node-gyp-build "^4.3.0" + bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -1453,7 +1780,7 @@ camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.0.0, camelcase@^6.2.0: +camelcase@^6.0.0, camelcase@^6.2.0, camelcase@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== @@ -1493,6 +1820,11 @@ chalk@^4.0.0, chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^5.3.0, chalk@^5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.4.1.tgz#1b48bf0963ec158dce2aacf69c093ae2dd2092d8" + integrity sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w== + char-regex@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" @@ -1587,6 +1919,21 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +commander@^12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3" + integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA== + +commander@^13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-13.1.0.tgz#776167db68c78f38dcce1f9b8d7b8b9a488abf46" + integrity sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw== + +commander@^2.20.3: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + component-emitter@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" @@ -1657,6 +2004,13 @@ cors@^2.8.5: object-assign "^4" vary "^1" +cross-fetch@^3.1.5: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.2.0.tgz#34e9192f53bc757d6614304d9e5e6fb4edb782e3" + integrity sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q== + dependencies: + node-fetch "^2.7.0" + cross-spawn@^7.0.0, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -1719,6 +2073,11 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== +delay@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" + integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1814,6 +2173,18 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== + dependencies: + es6-promise "^4.0.3" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -1892,6 +2263,16 @@ ethers@^5.0.0, ethers@^5.6.6: "@ethersproject/web" "5.7.1" "@ethersproject/wordlists" "5.7.0" +eventemitter3@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +eventemitter3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -1965,6 +2346,11 @@ express@^4.18.1: utils-merge "1.0.1" vary "~1.1.2" +eyes@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== + fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -1975,6 +2361,11 @@ fast-safe-stringify@^2.1.1: resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== +fast-stable-stringify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313" + integrity sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag== + fb-watchman@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" @@ -1982,6 +2373,11 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + filewatcher@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/filewatcher/-/filewatcher-3.0.1.tgz#f4a1957355ddaf443ccd78a895f3d55e23c8a034" @@ -2248,6 +2644,13 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -2255,6 +2658,11 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + import-local@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" @@ -2364,6 +2772,11 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" @@ -2406,6 +2819,24 @@ istanbul-reports@^3.1.3, istanbul-reports@^3.1.4: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +jayson@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/jayson/-/jayson-4.2.0.tgz#b71762393fa40bc9637eaf734ca6f40d3b8c0c93" + integrity sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg== + dependencies: + "@types/connect" "^3.4.33" + "@types/node" "^12.12.54" + "@types/ws" "^7.4.4" + commander "^2.20.3" + delay "^5.0.0" + es6-promisify "^5.0.0" + eyes "^0.1.8" + isomorphic-ws "^4.0.1" + json-stringify-safe "^5.0.1" + stream-json "^1.9.1" + uuid "^8.3.2" + ws "^7.5.10" + jest-changed-files@^29.5.0: version "29.5.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.5.0.tgz#e88786dca8bf2aa899ec4af7644e16d9dcf9b23e" @@ -2802,6 +3233,11 @@ json-parse-even-better-errors@^2.3.0: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== +json-stringify-safe@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + json5@^2.2.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" @@ -3036,7 +3472,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: +ms@2.1.3, ms@^2.0.0: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -3070,6 +3506,18 @@ node-dev@^7.4.3: resolve "^1.22.0" semver "^7.3.7" +node-fetch@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +node-gyp-build@^4.3.0: + version "4.8.4" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" + integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -3180,6 +3628,11 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +pako@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -3378,6 +3831,22 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +rpc-websockets@^9.0.2: + version "9.1.1" + resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-9.1.1.tgz#5764336f3623ee1c5cc8653b7335183e3c0c78bd" + integrity sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA== + dependencies: + "@swc/helpers" "^0.5.11" + "@types/uuid" "^8.3.4" + "@types/ws" "^8.2.2" + buffer "^6.0.3" + eventemitter3 "^5.0.1" + uuid "^8.3.2" + ws "^8.5.0" + optionalDependencies: + bufferutil "^4.0.1" + utf-8-validate "^5.0.2" + rxjs@^7.0.0: version "7.8.1" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" @@ -3390,7 +3859,7 @@ safe-buffer@5.1.2: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@^5.1.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -3539,6 +4008,18 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +stream-chain@^2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/stream-chain/-/stream-chain-2.2.5.tgz#b30967e8f14ee033c5b9a19bbe8a2cba90ba0d09" + integrity sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA== + +stream-json@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-1.9.1.tgz#e3fec03e984a503718946c170db7d74556c2a187" + integrity sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw== + dependencies: + stream-chain "^2.2.5" + string-length@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" @@ -3594,6 +4075,16 @@ superagent@^8.0.5: qs "^6.11.0" semver "^7.3.8" +superstruct@^0.15.4: + version "0.15.5" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.15.5.tgz#0f0a8d3ce31313f0d84c6096cd4fa1bfdedc9dab" + integrity sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ== + +superstruct@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-2.0.2.tgz#3f6d32fbdc11c357deff127d591a39b996300c54" + integrity sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A== + supertest@^6.2.4: version "6.3.3" resolved "https://registry.yarnpkg.com/supertest/-/supertest-6.3.3.tgz#42f4da199fee656106fd422c094cf6c9578141db" @@ -3637,6 +4128,11 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +text-encoding-utf-8@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" + integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -3659,6 +4155,16 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +toml@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" + integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + tree-kill@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" @@ -3683,6 +4189,11 @@ tslib@^2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913" integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== +tslib@^2.8.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" @@ -3701,10 +4212,10 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -typescript@^4.6.4: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@^5.0.0: + version "5.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" + integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" @@ -3719,12 +4230,19 @@ update-browserslist-db@^1.0.11: escalade "^3.1.1" picocolors "^1.0.0" +utf-8-validate@^5.0.2: + version "5.0.10" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== + dependencies: + node-gyp-build "^4.3.0" + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid@^8.3.0: +uuid@^8.3.0, uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== @@ -3750,6 +4268,19 @@ walker@^1.0.8: dependencies: makeerror "1.0.12" +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -3789,6 +4320,16 @@ ws@7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@^7.5.10: + version "7.5.10" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== + +ws@^8.5.0: + version "8.18.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" + integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== + xtend@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" diff --git a/backend/package.json b/backend/package.json index fbe6ccf..dc49324 100644 --- a/backend/package.json +++ b/backend/package.json @@ -18,7 +18,8 @@ "contracts:sync": "SCRIPT=./src/gotbit-tools/scripts/shell/import-contracts.sh yarn script", "contracts:typings": "node ./src/gotbit-tools/scripts/typings.js", "\n# UTILS SCRIPTS:": "", - "script": "chmod +x $SCRIPT && $SCRIPT" + "script": "chmod +x $SCRIPT && $SCRIPT", + "build-win": "rimraf dist && tsc -p ." }, "jest": { "preset": "ts-jest", diff --git a/backend/src/gotbit-tools/node/rpc.ts b/backend/src/gotbit-tools/node/rpc.ts index deff422..8d9f86f 100644 --- a/backend/src/gotbit-tools/node/rpc.ts +++ b/backend/src/gotbit-tools/node/rpc.ts @@ -1,3 +1,4 @@ +import { arbitrum_mainnet_rpc, arbitrum_sepolia_rpc, base_mainnet_rpc, base_spolia_rpc, binance_mainnet_rpc, binance_testnet_rpc, ethereum_mainnet_rpc, ethereum_sepolia_rpc, polygon_amoy_rpc, polygon_mainnet_rpc } from '@/utils/env-var' import { ChainTag, RemoteChainTag, RpcFunction } from './utils/misc' import { extraRpcs } from './utils/node' @@ -31,7 +32,7 @@ export const ankrRpc = (): RpcFunction => { if (chainTag === 'avax_testnet') return 'https://avalanche-fuji-c-chain.publicnode.com' - return 'https://rpc.ankr.com' + ankrPath[chainTag] ?? '' + return `https://rpc.ankr.com${ankrPath[chainTag]}` } } @@ -46,9 +47,11 @@ export const extraRpc = (indexes?: Partial>) => { } const rpcList = (extraRpcs as any)[chainTag] ?? [] - + for (const goodRpc of goodRpcProvider) { + const rpc = goodRpc(chainTag) + console.log(rpc) if (rpc) rpcList.push(rpc) } @@ -61,26 +64,26 @@ export const universalRpc = (): RpcFunction => { return (chainTag: ChainTag) => { const a: Record = { avax_mainnet: ankr(chainTag), - bsc_mainnet: ankr(chainTag), - arbitrum_mainnet: extraRpcs.arbitrum_mainnet[0], - eth_mainnet: ankr(chainTag), + bsc_mainnet: binance_mainnet_rpc, + arbitrum_mainnet: arbitrum_mainnet_rpc, + eth_mainnet: ethereum_mainnet_rpc, ftm_mainnet: ankr(chainTag), - polygon_mainnet: ankr(chainTag), + polygon_mainnet: polygon_mainnet_rpc, celo_mainnet: ankr(chainTag), - base_mainnet: ankr(chainTag), + base_mainnet: base_mainnet_rpc, bitlayer_mainnet: extraRpcs.bitlayer_mainnet[0], xend_mainnet: extraRpcs.xend_mainnet[0], avax_testnet: 'https://avalanche-fuji-c-chain.publicnode.com', - polygon_testnet: 'https://rpc-mumbai.maticvigil.com', + polygon_testnet: polygon_amoy_rpc, ftm_testnet: ankr(chainTag), rinkeby: ankr(chainTag), ropsten: ankr(chainTag), goerli: ankr(chainTag), - arbitrum_testnet: extraRpcs.arbitrum_testnet[0], + arbitrum_testnet: arbitrum_sepolia_rpc, // bsc_testnet: extraRpcs.bsc_testnet[0], - bsc_testnet: 'https://bsc-testnet.publicnode.com', + bsc_testnet: binance_testnet_rpc, localhost: extraRpcs.localhost[0], @@ -96,11 +99,11 @@ export const universalRpc = (): RpcFunction => { okex_testnet: extraRpcs.okex_testnet[0], cmp_testnet: extraRpcs.cmp_testnet[0], pulse_testnet: 'https://rpc.v4.testnet.pulsechain.com', - arbitrum_sepolia: extraRpcs.arbitrum_sepolia[0], + arbitrum_sepolia: arbitrum_sepolia_rpc, xend_testnet: extraRpcs.xend_testnet[0], - base_sepolia: extraRpcs.base_sepolia[0], - eth_sepolia: extraRpcs.eth_sepolia[0], - polygon_amoy: extraRpcs.polygon_amoy[0], + base_sepolia: base_spolia_rpc, + eth_sepolia: ethereum_sepolia_rpc, + polygon_amoy: polygon_amoy_rpc, bitlayer_testnet: extraRpcs.bitlayer_testnet[0], } as any return a[chainTag] diff --git a/backend/src/utils/env-var.ts b/backend/src/utils/env-var.ts new file mode 100644 index 0000000..88a74f9 --- /dev/null +++ b/backend/src/utils/env-var.ts @@ -0,0 +1,10 @@ +export const arbitrum_sepolia_rpc= process.env.ARBITRIUM_SEPOLIA_RPC +export const arbitrum_mainnet_rpc= process.env.ARBITRIUM_MAINNET_RPC +export const ethereum_sepolia_rpc= process.env.ETHEREUM_SEPOLIA_RPC +export const ethereum_mainnet_rpc= process.env.ETHEREUM_MAINNET_RPC +export const polygon_amoy_rpc= process.env.POLYGON_AMOY_RPC +export const polygon_mainnet_rpc= process.env.POLYGON_MAINNET_RPC +export const base_spolia_rpc= process.env.BASE_SEPOLIA_RPC +export const base_mainnet_rpc= process.env.BASE_MAINNET_RPC +export const binance_testnet_rpc= process.env.BINANCE_TESTNET_RPC +export const binance_mainnet_rpc= process.env.BINANCE_MAINNET_RPC \ No newline at end of file From 3b9232d68519dc53bc2f5c71c130977409d11d55 Mon Sep 17 00:00:00 2001 From: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> Date: Mon, 22 Sep 2025 11:16:28 +0100 Subject: [PATCH 14/19] support multiple solana bridges (#94) * working solana bridge * integrated solana * working on solanan * trying to reduce time for server response (#92) * Main (#81) * fix var issue (#80) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) Co-authored-by: Franklin Nwanze * Update blockchain.ts * Update blockchain.ts * fix bug (#78) (#79) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) * Update blockchain.ts * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * log to check error * changes to backend * added deploy script * added deploy script --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * worked on multiple rpc * Rpc (#82) * fix var issue (#80) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) Co-authored-by: Franklin Nwanze * Update blockchain.ts * Update blockchain.ts * fix bug (#78) (#79) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) * Update blockchain.ts * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * log to check error * changes to backend * added deploy script * added deploy script * add deploy script for xRWA * checking error * removed logs * [chores] use multiple rpc * worked on multiple rpc --------- Co-authored-by: Franklin * polygon support * polygon support (#84) * use polygon rpc from env * finish wnt-restriction on arb (#88) * changed block number * fix wnt restriction bug * trying to reduce time for server response * fix bug * fix bug --------- Co-authored-by: Franklin * finish solana * support multiple solana bridges --------- Co-authored-by: Franklin --- backend-all/src/routes/sign-solana-evm.ts | 7 +++++-- backend-all/src/routes/sign-solana.ts | 6 ++++-- backend-all/src/services/blockchain.ts | 15 ++++++++++----- backend-all/src/types/index.ts | 1 + backend-all/src/utils/solana/helpers.ts | 13 +++++++++---- 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/backend-all/src/routes/sign-solana-evm.ts b/backend-all/src/routes/sign-solana-evm.ts index 5ff52d7..e4fa411 100644 --- a/backend-all/src/routes/sign-solana-evm.ts +++ b/backend-all/src/routes/sign-solana-evm.ts @@ -8,8 +8,8 @@ import { GetTransactionSignationDto } from '@/types' export default (): Resource => ({ async get(req: Request<{}, {}, {}, GetTransactionSignationDto>, res) { try { - const { fromBridgeAddress, toBridgeAssistAddress, fromChain, fromUser, index } = - req.query + + const { fromBridgeAddress, toBridgeAssistAddress, fromChain, fromUser, index, _tokenMint } = req.query if (!fromBridgeAddress) return res.status(400).send('fromBridgeAddress not specified') @@ -18,6 +18,8 @@ export default (): Resource => ({ if (!fromChain) return res.status(400).send('from chain not specified') if (!fromUser) return res.status(400).send('from user not specified') if (!index) return res.status(400).send('index not specified') + if (!_tokenMint) return res.status(400).send('token mint not specified') + const signature = await signSolanaToEvm( req, fromChain, @@ -25,6 +27,7 @@ export default (): Resource => ({ toBridgeAssistAddress, fromUser, index, + _tokenMint ) res.status(200).json({signature}) diff --git a/backend-all/src/routes/sign-solana.ts b/backend-all/src/routes/sign-solana.ts index a473612..ef6b79b 100644 --- a/backend-all/src/routes/sign-solana.ts +++ b/backend-all/src/routes/sign-solana.ts @@ -8,8 +8,8 @@ import { GetTransactionSignationDto } from '@/types' export default (): Resource => ({ async get(req: Request<{}, {}, {}, GetTransactionSignationDto>, res) { try { - const { fromBridgeAddress, toBridgeAssistAddress, fromChain, fromUser, index } = - req.query + + const { fromBridgeAddress, toBridgeAssistAddress, fromChain, fromUser, index, _tokenMint } = req.query if (!fromBridgeAddress) return res.status(400).send('fromBridgeAddress not specified') @@ -18,12 +18,14 @@ export default (): Resource => ({ if (!fromChain) return res.status(400).send('from chain not specified') if (!fromUser) return res.status(400).send('from user not specified') if (!index) return res.status(400).send('index not specified') + if (!_tokenMint) return res.status(400).send('token mint not specified') const signature = await signEvmToSolana( fromChain, fromBridgeAddress, toBridgeAssistAddress, fromUser, index, + _tokenMint ) res.status(200).json({signature}) diff --git a/backend-all/src/services/blockchain.ts b/backend-all/src/services/blockchain.ts index 3fe443d..86d99e9 100644 --- a/backend-all/src/services/blockchain.ts +++ b/backend-all/src/services/blockchain.ts @@ -173,9 +173,11 @@ export async function signEvmToSolana( fromBridgeAddress: string, toBridgeAddress: string, fromUser: string, - index: string + index: string, + _tokenMint: string ) { - const { tokenMint, connection, owner } = solanaWorkspace(toBridgeAddress) + const { tokenMint, connection, owner } = solanaWorkspace(toBridgeAddress, _tokenMint) + // console.log(connection, 'connection') const fromChain = fromChainId.slice(4) as ChainId @@ -192,7 +194,7 @@ export async function signEvmToSolana( console.log(userTokenAccountKey.toBase58(), 'kdkdsk') const extractedTx = extractTransaction(tx) - if (await isToSolanaTxFulfilled(toBridgeAddress, fromChain, tx.nonce)) + if (await isToSolanaTxFulfilled(toBridgeAddress, _tokenMint, fromChain, tx.nonce)) throw Error('Already claimed') @@ -203,6 +205,7 @@ export async function signEvmToSolana( const signature = await signSolana( toBridgeAddress, extractedTx, + _tokenMint, userTokenAccountKey ) @@ -215,9 +218,11 @@ export async function signSolanaToEvm( fromBridgeAddress: string, toBridgeAddress: string, userSolana: string, - nonce: string + nonce: string, + _tokenMint: string ) { - const { owner, tokenMint, program, connection } = solanaWorkspace(fromBridgeAddress) + const { owner, tokenMint, program, connection } = solanaWorkspace(fromBridgeAddress, _tokenMint) + const tx = await getSolanaSendTx( owner, tokenMint, diff --git a/backend-all/src/types/index.ts b/backend-all/src/types/index.ts index 8fa2cf9..fea9525 100644 --- a/backend-all/src/types/index.ts +++ b/backend-all/src/types/index.ts @@ -68,6 +68,7 @@ export interface GetTransactionSignationDto { fromChain?: string fromUser?: string index?: string + _tokenMint?: string } export interface FulfillTxContract { diff --git a/backend-all/src/utils/solana/helpers.ts b/backend-all/src/utils/solana/helpers.ts index d4f039b..97276d6 100644 --- a/backend-all/src/utils/solana/helpers.ts +++ b/backend-all/src/utils/solana/helpers.ts @@ -46,7 +46,8 @@ const secretKey = bs58.decode(process.env.SOLANA_KEY!) * @returns workspace.provider The Solana provider. * @returns workspace.program The Solana program. */ -export const solanaWorkspace = (bridgeAssist: string) => { +export const solanaWorkspace = (bridgeAssist: string, tokenMint: string) => { + const owner = Keypair.fromSecretKey(secretKey) const network = clusterApiUrl(isMain ? 'mainnet-beta' : 'devnet') @@ -55,7 +56,7 @@ export const solanaWorkspace = (bridgeAssist: string) => { preflightCommitment: 'confirmed', }) const program = new Program(IDL, provider) - const tokenMint = (SOLANABRIDGE_TOKENS as any)[bridgeAssist] + if (!tokenMint) throw new Error(`Token mint not initialized`) return { @@ -194,10 +195,12 @@ const getEmptyAccount = ( export async function isToSolanaTxFulfilled( toBridgeAddress: string, + _tokenMint: string, fromChainId: ChainId, nonce: BigNumber ): Promise { - const { owner, tokenMint, program } = solanaWorkspace(toBridgeAddress) + const { owner, program,tokenMint } = solanaWorkspace(toBridgeAddress, _tokenMint) + // const { bridgeAssist } = useContracts(undefined, fromChainId) // const CURRENT_CHAIN = await safeRead(bridgeAssist.CURRENT_CHAIN(), 'INVALID') @@ -245,9 +248,11 @@ export async function isToSolanaTxFulfilled( export const signSolana = async ( toBridgeAddress: string, tx: ExtractedTransaction, + _tokenMint: string, userTokenAccount: PublicKey ) => { - const { owner, tokenMint, program, connection } = solanaWorkspace(toBridgeAddress) + const { owner, program, tokenMint, connection } = solanaWorkspace(toBridgeAddress, _tokenMint) + const user = new PublicKey(tx.toUser) console.log(user.toBase58(), 'toUser') const bridgeTokenAccount = getBridgeAccount( From 702a17109e22070bad7b9ca7231123ab926621b7 Mon Sep 17 00:00:00 2001 From: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> Date: Sat, 11 Oct 2025 10:39:49 +0100 Subject: [PATCH 15/19] Redesign backend to for the bridge frontend (#95) * trying to reduce time for server response (#92) * Main (#81) * fix var issue (#80) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) Co-authored-by: Franklin Nwanze * Update blockchain.ts * Update blockchain.ts * fix bug (#78) (#79) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) * Update blockchain.ts * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * log to check error * changes to backend * added deploy script * added deploy script --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * worked on multiple rpc * Rpc (#82) * fix var issue (#80) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) Co-authored-by: Franklin Nwanze * Update blockchain.ts * Update blockchain.ts * fix bug (#78) (#79) * Init backend restructure * added condition for other relayers * added condition for other relayers * added condition for other relayers * [Update]: Update backend code * Create parse-apps2.config.js * Create parse-apps3.config.js * [Update]: Changed to use structure * new-structure * changed rpc for arb testnet * changed rpc for arb testnet * change rpc * change rpc * Update push-prod.yml * added IP whitelist (#75) * Update blockchain.ts * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * Update blockchain.ts --------- Co-authored-by: stephenson080 Co-authored-by: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> * log to check error * changes to backend * added deploy script * added deploy script * add deploy script for xRWA * checking error * removed logs * [chores] use multiple rpc * worked on multiple rpc --------- Co-authored-by: Franklin * polygon support * polygon support (#84) * use polygon rpc from env * finish wnt-restriction on arb (#88) * changed block number * fix wnt restriction bug * trying to reduce time for server response * fix bug * fix bug --------- Co-authored-by: Franklin * redesign * redesign bridge backend * working on bridge transactions * redesign backend * fixed error * bug fixes --------- Co-authored-by: Franklin --- backend-all/package.json | 16 +- backend-all/src/app.ts | 52 +- backend-all/src/config.ts | 14 +- backend-all/src/confirmations.json | 8 +- backend-all/src/lib/database/connection.ts | 88 ++ backend-all/src/lib/database/data-source.ts | 21 + .../src/lib/database/entities/BaseEntity.ts | 12 + .../lib/database/entities/BlockscanInfo.ts | 14 + .../src/lib/database/entities/BridgeInfo.ts | 38 + .../src/lib/database/entities/Token.ts | 24 + .../src/lib/database/entities/Transaction.ts | 85 ++ .../database/entities/UserTransactionSync.ts | 15 + .../src/lib/database/entities/index.ts | 6 + backend-all/src/lib/database/index.ts | 4 + .../src/lib/database/migrations/.gitkeep | 2 + .../1700000000001-CreateTokenAndBridgeInfo.ts | 114 +++ .../1700000000002-CreateTransaction.ts | 166 ++++ .../1700000000003-CreateBlockscanInfo.ts | 68 ++ ...1700000000004-CreateUserTransactionSync.ts | 48 ++ ...0000005-AddTransactionDateToTransaction.ts | 26 + ...0006-AddBridgeInfoRelationToTransaction.ts | 38 + ...00000000007-MakeTransactionHashNullable.ts | 21 + ...00008-AddChainTypeToUserTransactionSync.ts | 44 + ...000009-AddClaimTransactionToTransaction.ts | 18 + .../repositories/BlockscanInfoRepository.ts | 191 +++++ .../repositories/BridgeInfoRepository.ts | 126 +++ .../database/repositories/TokenRepository.ts | 109 +++ .../repositories/TransactionRepository.ts | 352 ++++++++ .../UserTransactionSyncRepository.ts | 29 + .../src/lib/database/repositories/index.ts | 16 + backend-all/src/lib/database/seeders/index.ts | 40 + .../src/lib/database/subscribers/.gitkeep | 2 + backend-all/src/lib/logger/index.logger.ts | 23 + backend-all/src/lib/logger/logger.ts | 27 + backend-all/src/routes/bridges/index.ts | 19 + backend-all/src/routes/seed-tokens.ts | 16 + backend-all/src/routes/sign-solana-evm.ts | 23 +- backend-all/src/routes/sign-solana.ts | 19 +- backend-all/src/routes/sign.ts | 6 +- .../src/routes/tokens/balance-by-blocktag.ts | 39 + backend-all/src/routes/tokens/index.ts | 19 + backend-all/src/routes/transactions/index.ts | 99 +++ backend-all/src/services/blockchain.ts | 104 ++- backend-all/src/services/bridge.ts | 809 ++++++++++++++++++ backend-all/src/services/index.ts | 7 + backend-all/src/services/token.ts | 189 ++++ backend-all/src/types/index.ts | 35 +- backend-all/src/utils/constant.ts | 417 ++++----- backend-all/src/utils/env-var.ts | 39 +- backend-all/src/utils/helpers.ts | 26 +- backend-all/src/utils/solana/helpers.ts | 5 +- backend-all/tsconfig.json | 5 +- backend-all/yarn.lock | 734 +++++++++++++++- 53 files changed, 4175 insertions(+), 292 deletions(-) create mode 100644 backend-all/src/lib/database/connection.ts create mode 100644 backend-all/src/lib/database/data-source.ts create mode 100644 backend-all/src/lib/database/entities/BaseEntity.ts create mode 100644 backend-all/src/lib/database/entities/BlockscanInfo.ts create mode 100644 backend-all/src/lib/database/entities/BridgeInfo.ts create mode 100644 backend-all/src/lib/database/entities/Token.ts create mode 100644 backend-all/src/lib/database/entities/Transaction.ts create mode 100644 backend-all/src/lib/database/entities/UserTransactionSync.ts create mode 100644 backend-all/src/lib/database/entities/index.ts create mode 100644 backend-all/src/lib/database/index.ts create mode 100644 backend-all/src/lib/database/migrations/.gitkeep create mode 100644 backend-all/src/lib/database/migrations/1700000000001-CreateTokenAndBridgeInfo.ts create mode 100644 backend-all/src/lib/database/migrations/1700000000002-CreateTransaction.ts create mode 100644 backend-all/src/lib/database/migrations/1700000000003-CreateBlockscanInfo.ts create mode 100644 backend-all/src/lib/database/migrations/1700000000004-CreateUserTransactionSync.ts create mode 100644 backend-all/src/lib/database/migrations/1700000000005-AddTransactionDateToTransaction.ts create mode 100644 backend-all/src/lib/database/migrations/1700000000006-AddBridgeInfoRelationToTransaction.ts create mode 100644 backend-all/src/lib/database/migrations/1700000000007-MakeTransactionHashNullable.ts create mode 100644 backend-all/src/lib/database/migrations/1700000000008-AddChainTypeToUserTransactionSync.ts create mode 100644 backend-all/src/lib/database/migrations/1700000000009-AddClaimTransactionToTransaction.ts create mode 100644 backend-all/src/lib/database/repositories/BlockscanInfoRepository.ts create mode 100644 backend-all/src/lib/database/repositories/BridgeInfoRepository.ts create mode 100644 backend-all/src/lib/database/repositories/TokenRepository.ts create mode 100644 backend-all/src/lib/database/repositories/TransactionRepository.ts create mode 100644 backend-all/src/lib/database/repositories/UserTransactionSyncRepository.ts create mode 100644 backend-all/src/lib/database/repositories/index.ts create mode 100644 backend-all/src/lib/database/seeders/index.ts create mode 100644 backend-all/src/lib/database/subscribers/.gitkeep create mode 100644 backend-all/src/lib/logger/index.logger.ts create mode 100644 backend-all/src/lib/logger/logger.ts create mode 100644 backend-all/src/routes/bridges/index.ts create mode 100644 backend-all/src/routes/seed-tokens.ts create mode 100644 backend-all/src/routes/tokens/balance-by-blocktag.ts create mode 100644 backend-all/src/routes/tokens/index.ts create mode 100644 backend-all/src/routes/transactions/index.ts create mode 100644 backend-all/src/services/bridge.ts create mode 100644 backend-all/src/services/index.ts create mode 100644 backend-all/src/services/token.ts diff --git a/backend-all/package.json b/backend-all/package.json index b6cabfe..92367df 100644 --- a/backend-all/package.json +++ b/backend-all/package.json @@ -17,6 +17,13 @@ "contracts": "yarn contracts:sync && yarn contracts:typings", "contracts:sync": "SCRIPT=./src/gotbit-tools/scripts/shell/import-contracts.sh yarn script", "contracts:typings": "node ./src/gotbit-tools/scripts/typings.js", + "typeorm": "typeorm-ts-node-commonjs", + "migration:generate": "yarn typeorm migration:generate -d src/lib/database/data-source.ts", + "migration:run": "yarn typeorm migration:run -d src/lib/database/data-source.ts", + "migration:revert": "yarn typeorm migration:revert -d src/lib/database/data-source.ts", + "migration:show": "yarn typeorm migration:show -d src/lib/database/data-source.ts", + "schema:sync": "yarn typeorm schema:sync -d src/lib/database/data-source.ts", + "schema:drop": "yarn typeorm schema:drop -d src/lib/database/data-source.ts", "\n# UTILS SCRIPTS:": "", "script": "chmod +x $SCRIPT && $SCRIPT", "dev-win": "yarn build-win && concurrently \"tsc -w\" \"cross-env DEBUG=true node-dev --respawn dist/app.js\"", @@ -46,7 +53,7 @@ "dependencies": { "@coral-xyz/anchor": "^0.31.1", "@solana/spl-token": "^0.4.13", - "@solana/web3.js": "^1.98.2", + "@solana/web3.js": "^1.98.4", "axios": "^0.27.2", "body-parser": "^1.20.0", "bs58": "^6.0.0", @@ -59,7 +66,11 @@ "helmet": "^5.0.2", "module-alias": "^2.2.2", "moment": "^2.29.3", - "morgan": "^1.10.0" + "morgan": "^1.10.0", + "pg": "^8.8.0", + "reflect-metadata": "^0.1.13", + "typeorm": "^0.3.12", + "winston": "^3.17.0" }, "devDependencies": { "@types/chai": "^4.3.3", @@ -69,6 +80,7 @@ "@types/mocha": "^9.1.1", "@types/morgan": "^1.9.3", "@types/node": "^17.0.31", + "@types/pg": "^8.6.6", "@types/supertest": "^2.0.12", "c8": "^7.11.3", "chai": "^4.3.6", diff --git a/backend-all/src/app.ts b/backend-all/src/app.ts index 5b32e58..dd4c3be 100644 --- a/backend-all/src/app.ts +++ b/backend-all/src/app.ts @@ -1,3 +1,4 @@ +import 'reflect-metadata' import express from 'express' import path from 'path' @@ -10,7 +11,9 @@ import 'module-alias/register' import * as dotenv from 'dotenv' dotenv.config() -import config from '@/config' +import { config } from '@/config' +import { dbConnection } from '@/lib/database' +import { isPublicRelayer } from './utils/env-var' const app = express() @@ -20,10 +23,47 @@ autoroutes(app, { dir: path.join(__dirname, 'routes'), }) -if (!process.env.TEST) - app.listen(config.port, () => { - console.log(`Server started on port ${config.port}`) - console.log(`DEBUG=${process.env.DEBUG}`) - }) +// Initialize database connection and start server +const startServer = async () => { + try { + // Connect to database + + if (isPublicRelayer) { + await dbConnection.connect() + + // Run migrations on startup (optional - you might want to run them manually) + await dbConnection.runMigrations() + } + + if (!process.env.TEST) { + app.listen(config.port, () => { + console.log(`Server started on port ${config.port}`) + console.log(`DEBUG=${process.env.DEBUG}`) + console.log('Database connected successfully') + }) + } + } catch (error) { + console.error('Failed to start server:', error) + process.exit(1) + } +} + +// Graceful shutdown +process.on('SIGINT', async () => { + console.log('Shutting down gracefully...') + + + await dbConnection.disconnect() + process.exit(0) +}) + +process.on('SIGTERM', async () => { + console.log('Shutting down gracefully...') + + await dbConnection.disconnect() + process.exit(0) +}) + +startServer() export default app diff --git a/backend-all/src/config.ts b/backend-all/src/config.ts index 93454c9..14efebf 100644 --- a/backend-all/src/config.ts +++ b/backend-all/src/config.ts @@ -1,5 +1,15 @@ -export default { +console.log(process.env.DATABASE_USERNAME) +export const config = { morganLogger: ':date[web] :method :url :status :res[content-length] - :response-time ms', port: process.env.PORT, -} + database: { + host: process.env.DATABASE_HOST || 'localhost', + port: parseInt(process.env.DATABASE_PORT || '5432'), + username: process.env.DATABASE_USERNAME || 'postgres', + password: process.env.DATABASE_PASSWORD || 'password', + database: process.env.DATABASE_NAME || 'assetchain_bridge', + logging: process.env.DB_LOGGING === 'true', + ssl: process.env.DB_SSL === 'true', + }, +}; diff --git a/backend-all/src/confirmations.json b/backend-all/src/confirmations.json index b5e6def..f84aa10 100644 --- a/backend-all/src/confirmations.json +++ b/backend-all/src/confirmations.json @@ -12,12 +12,14 @@ "80001": 42, "421614": 42, "8453": 42, - "42421": 42, + "42421": 5, "80002": 42, "84532": 42, "11155111": 42, "200810": 42, "200901": 42, - "42420": 42, - "solana": 100 + "42420": 5, + "solana": 100, + "sol.devnet": 100, + "sol.mainnet": 100 } diff --git a/backend-all/src/lib/database/connection.ts b/backend-all/src/lib/database/connection.ts new file mode 100644 index 0000000..6eb057f --- /dev/null +++ b/backend-all/src/lib/database/connection.ts @@ -0,0 +1,88 @@ +import "reflect-metadata"; +import { DataSource } from "typeorm"; +import { AppDataSource } from "./data-source"; +import EventLogger from "../logger/index.logger"; + +class DatabaseConnection { + private static instance: DatabaseConnection; + private dataSource: DataSource | null = null; + + private constructor() {} + + public static getInstance(): DatabaseConnection { + if (!DatabaseConnection.instance) { + DatabaseConnection.instance = new DatabaseConnection(); + } + return DatabaseConnection.instance; + } + + public async connect() { + try { + if (!this.dataSource) { + this.dataSource = AppDataSource; + await this.dataSource.initialize(); + EventLogger.info("Database connection established successfully"); + } + return this.dataSource; + } catch (error: any) { + EventLogger.error(`Error connecting to database ${error.message}`); + throw error; + } + } + + public async disconnect() { + try { + if (this.dataSource && this.dataSource.isInitialized) { + await this.dataSource.destroy(); + this.dataSource = null; + EventLogger.info("Database connection closed"); + } + } catch (error:any) { + EventLogger.error("Error disconnecting from database:" + error.message); + throw error; + } + } + + public getDataSource() { + return this.dataSource; + } + + public async runMigrations() { + try { + if (!this.dataSource) { + await this.connect(); + } + + if (this.dataSource && this.dataSource.isInitialized) { + await this.dataSource.runMigrations(); + EventLogger.info("Migrations completed successfully"); + } + } catch (error:any) { + EventLogger.error("Error running migrations:" + error.message); + throw error; + } + } + + public async undoLastMigration() { + try { + if (!this.dataSource) { + await this.connect(); + } + + if (this.dataSource && this.dataSource.isInitialized) { + await this.dataSource.undoLastMigration(); + EventLogger.info("Last migration reverted successfully"); + } + } catch (error:any) { + EventLogger.error("Error reverting migration:" + error.message); + throw error; + } + } + + public isConnected() { + return this.dataSource ? this.dataSource.isInitialized : false; + } +} + +export const dbConnection = DatabaseConnection.getInstance(); +export default dbConnection; diff --git a/backend-all/src/lib/database/data-source.ts b/backend-all/src/lib/database/data-source.ts new file mode 100644 index 0000000..50229c1 --- /dev/null +++ b/backend-all/src/lib/database/data-source.ts @@ -0,0 +1,21 @@ +import "reflect-metadata"; +import { DataSource } from "typeorm"; +import { config } from "../../config"; + +export const AppDataSource = new DataSource({ + type: "postgres", + host: config.database.host, + port: config.database.port, + username: config.database.username, + password: config.database.password, + database: config.database.database, + synchronize: false, // Set to false when using migrations + logging: config.database.logging || false, + entities: [__dirname + "/entities/*.{ts,js}"], + migrations: [__dirname + "/migrations/*.{ts,js}"], + subscribers: [__dirname + "/subscribers/*.{ts,js}"], + migrationsTableName: "migrations", + ssl: config.database.ssl ? { rejectUnauthorized: false } : false, +}); + +export default AppDataSource; diff --git a/backend-all/src/lib/database/entities/BaseEntity.ts b/backend-all/src/lib/database/entities/BaseEntity.ts new file mode 100644 index 0000000..026f12a --- /dev/null +++ b/backend-all/src/lib/database/entities/BaseEntity.ts @@ -0,0 +1,12 @@ +import { PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from "typeorm"; + +export abstract class BaseEntity { + @PrimaryGeneratedColumn("uuid") + id: string; + + @CreateDateColumn() + createdAt: Date; + + @UpdateDateColumn() + updatedAt: Date; +} diff --git a/backend-all/src/lib/database/entities/BlockscanInfo.ts b/backend-all/src/lib/database/entities/BlockscanInfo.ts new file mode 100644 index 0000000..ab7aa19 --- /dev/null +++ b/backend-all/src/lib/database/entities/BlockscanInfo.ts @@ -0,0 +1,14 @@ +import { Entity, Column } from "typeorm"; +import { BaseEntity } from "./BaseEntity"; + +@Entity("blockscan_infos") +export class BlockscanInfo extends BaseEntity { + @Column({ type: "text" }) + lastBlockScanned: string; // Using text for very long block numbers + + @Column() + chainId: string; + + @Column() + contractAddress: string; +} diff --git a/backend-all/src/lib/database/entities/BridgeInfo.ts b/backend-all/src/lib/database/entities/BridgeInfo.ts new file mode 100644 index 0000000..4eb78e6 --- /dev/null +++ b/backend-all/src/lib/database/entities/BridgeInfo.ts @@ -0,0 +1,38 @@ +import { Entity, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm"; +import { BaseEntity } from "./BaseEntity"; +import { Token } from "./Token"; +import { Transaction } from "./Transaction"; + +@Entity("bridge_infos") +export class BridgeInfo extends BaseEntity { + @Column() + bridgeAddress: string; + + @Column() + chainId: string; + + @Column({ type: "jsonb" }) + fees: { + feeFulfill: number; + feeSend: number; + }; + + @ManyToOne("Token", "bridgeInfos", { + onDelete: "CASCADE", + nullable: false + }) + @JoinColumn({ name: "tokenId" }) + token: Token; + + @Column() + tokenId: string; + + @Column({ type: "text" }) + limitPerSend: string; + + @Column() + tokenDecimal: number; + + @OneToMany(() => Transaction, (transaction) => transaction.bridgeInfo) + transactions: Transaction[]; +} diff --git a/backend-all/src/lib/database/entities/Token.ts b/backend-all/src/lib/database/entities/Token.ts new file mode 100644 index 0000000..b300af8 --- /dev/null +++ b/backend-all/src/lib/database/entities/Token.ts @@ -0,0 +1,24 @@ +import { Entity, Column, OneToMany } from "typeorm"; +import { BaseEntity } from "./BaseEntity"; +import { BridgeInfo } from "./BridgeInfo"; + +@Entity("tokens") +export class Token extends BaseEntity { + @Column() + tokenAddress: string; + + @Column() + decimal: number; + + @Column() + symbol: string; + + @Column() + name: string; + + @Column() + chainId: string; + + @OneToMany("BridgeInfo", "token") + bridgeInfos: BridgeInfo[]; +} diff --git a/backend-all/src/lib/database/entities/Transaction.ts b/backend-all/src/lib/database/entities/Transaction.ts new file mode 100644 index 0000000..49d0f0a --- /dev/null +++ b/backend-all/src/lib/database/entities/Transaction.ts @@ -0,0 +1,85 @@ +import { Entity, Column, ManyToOne, JoinColumn } from "typeorm"; +import { BaseEntity } from "./BaseEntity"; +import { BridgeInfo } from "./BridgeInfo"; + +@Entity("transactions") +export class Transaction extends BaseEntity { + // From BridgeTransaction + @Column({ type: "text" }) + amount: string; // Using text for very long bigint values + + @Column({ type: "text" }) + timestamp: string; // Using text for very long bigint values + + @Column() + fromUser: string; + + @Column() + toUser: string; + + @Column() + fromChain: string; + + @Column() + toChain: string; + + @Column() + nonce: number; + + @Column() + symbol: string; + + // From FulfilTransaction + @Column({ type: "text" }) + fulfillAmount: string; // Using text for very long bigint values + + @Column() + fulfillFromChain: string; + + @Column() + fulfillNonce: number; + + @Column() + fulfillFromUser: string; + + @Column() + fulfillToUser: string; + + // From ClaimInfo + @Column({ type: "text" }) + txBlock: string; // Using text for very long bigint values + + @Column() + confirmations: number; + + // Additional fields + @Column() + fulfilled: boolean; + + @Column() + index: number; + + // New fields requested + @Column() + userAddress: string; + + @Column() + chainId: string; + + @Column({ nullable: true }) + transactionHash: string; + + @Column({ nullable: true }) + claimTransactionHash: string; + + @Column({ type: "timestamp" }) + transactionDate: Date; + + // map to BridgeInfo + @Column() + bridgeInfoId: string; + + @ManyToOne(() => BridgeInfo, (bridgeInfo) => bridgeInfo.transactions) + @JoinColumn({ name: "bridgeInfoId" }) + bridgeInfo: BridgeInfo; +} diff --git a/backend-all/src/lib/database/entities/UserTransactionSync.ts b/backend-all/src/lib/database/entities/UserTransactionSync.ts new file mode 100644 index 0000000..dcac85f --- /dev/null +++ b/backend-all/src/lib/database/entities/UserTransactionSync.ts @@ -0,0 +1,15 @@ +import { Entity, Column } from "typeorm"; +import { BaseEntity } from "./BaseEntity"; +import { ChainType } from "@/types"; + +@Entity("user_transaction_syncs") +export class UserTransactionSync extends BaseEntity { + @Column() + userAddress: string; + + @Column({ default: false }) + synced: boolean; + + @Column({ default: ChainType.EVM }) + chainType: ChainType; +} diff --git a/backend-all/src/lib/database/entities/index.ts b/backend-all/src/lib/database/entities/index.ts new file mode 100644 index 0000000..0fde010 --- /dev/null +++ b/backend-all/src/lib/database/entities/index.ts @@ -0,0 +1,6 @@ +// Export all entities here +export { BaseEntity } from "./BaseEntity"; +export { Token } from "./Token"; +export { BridgeInfo } from "./BridgeInfo"; + +// Add your entity exports as you create them diff --git a/backend-all/src/lib/database/index.ts b/backend-all/src/lib/database/index.ts new file mode 100644 index 0000000..d59b499 --- /dev/null +++ b/backend-all/src/lib/database/index.ts @@ -0,0 +1,4 @@ +export { AppDataSource } from "./data-source"; +export { dbConnection } from "./connection"; +export * from "./repositories"; +export * from "./entities"; diff --git a/backend-all/src/lib/database/migrations/.gitkeep b/backend-all/src/lib/database/migrations/.gitkeep new file mode 100644 index 0000000..330a1c7 --- /dev/null +++ b/backend-all/src/lib/database/migrations/.gitkeep @@ -0,0 +1,2 @@ +# This file ensures the migrations directory is tracked by git +# TypeORM migrations will be generated here diff --git a/backend-all/src/lib/database/migrations/1700000000001-CreateTokenAndBridgeInfo.ts b/backend-all/src/lib/database/migrations/1700000000001-CreateTokenAndBridgeInfo.ts new file mode 100644 index 0000000..ee9db6f --- /dev/null +++ b/backend-all/src/lib/database/migrations/1700000000001-CreateTokenAndBridgeInfo.ts @@ -0,0 +1,114 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CreateTokenAndBridgeInfo1700000000001 implements MigrationInterface { + name = 'CreateTokenAndBridgeInfo1700000000001' + + public async up(queryRunner: QueryRunner): Promise { + // Enable UUID extension + await queryRunner.query(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`); + + // Create tokens table + await queryRunner.query(` + CREATE TABLE "tokens" ( + "id" uuid NOT NULL DEFAULT uuid_generate_v4(), + "tokenAddress" character varying NOT NULL, + "decimal" integer NOT NULL, + "symbol" character varying NOT NULL, + "name" character varying NOT NULL, + "chainId" character varying NOT NULL, + "createdAt" TIMESTAMP NOT NULL DEFAULT now(), + "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), + CONSTRAINT "PK_tokens_id" PRIMARY KEY ("id") + ) + `); + + // Create bridge_infos table + await queryRunner.query(` + CREATE TABLE "bridge_infos" ( + "id" uuid NOT NULL DEFAULT uuid_generate_v4(), + "bridgeAddress" character varying NOT NULL, + "chainId" character varying NOT NULL, + "fees" jsonb NOT NULL, + "tokenId" uuid NOT NULL, + "limitPerSend" text NOT NULL, + "tokenDecimal" integer NOT NULL, + "createdAt" TIMESTAMP NOT NULL DEFAULT now(), + "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), + CONSTRAINT "PK_bridge_infos_id" PRIMARY KEY ("id") + ) + `); + + // Create foreign key constraint + await queryRunner.query(` + ALTER TABLE "bridge_infos" + ADD CONSTRAINT "FK_bridge_infos_tokenId" + FOREIGN KEY ("tokenId") + REFERENCES "tokens"("id") + ON DELETE CASCADE ON UPDATE NO ACTION + `); + + // Create indexes for better performance + await queryRunner.query(` + CREATE INDEX "IDX_tokens_chainId" ON "tokens" ("chainId") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_tokens_symbol" ON "tokens" ("symbol") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_bridge_infos_chainId" ON "bridge_infos" ("chainId") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_bridge_infos_tokenId" ON "bridge_infos" ("tokenId") + `); + + // Add check constraints for fees JSON structure + await queryRunner.query(` + ALTER TABLE "bridge_infos" + ADD CONSTRAINT "CHK_bridge_infos_fees_structure" + CHECK ( + jsonb_typeof("fees") = 'object' AND + "fees" ? 'feeFulfill' AND + "fees" ? 'feeSend' AND + jsonb_typeof("fees"->'feeFulfill') = 'number' AND + jsonb_typeof("fees"->'feeSend') = 'number' + ) + `); + + // Add check constraints for positive values + await queryRunner.query(` + ALTER TABLE "tokens" + ADD CONSTRAINT "CHK_tokens_decimal_positive" + CHECK ("decimal" > 0) + `); + + + await queryRunner.query(` + ALTER TABLE "bridge_infos" + ADD CONSTRAINT "CHK_bridge_infos_tokenDecimal_positive" + CHECK ("tokenDecimal" > 0) + `); + } + + public async down(queryRunner: QueryRunner): Promise { + // Drop check constraints + await queryRunner.query(`ALTER TABLE "bridge_infos" DROP CONSTRAINT "CHK_bridge_infos_tokenDecimal_positive"`); + await queryRunner.query(`ALTER TABLE "tokens" DROP CONSTRAINT "CHK_tokens_decimal_positive"`); + await queryRunner.query(`ALTER TABLE "bridge_infos" DROP CONSTRAINT "CHK_bridge_infos_fees_structure"`); + + // Drop indexes + await queryRunner.query(`DROP INDEX "IDX_bridge_infos_tokenId"`); + await queryRunner.query(`DROP INDEX "IDX_bridge_infos_chainId"`); + await queryRunner.query(`DROP INDEX "IDX_tokens_symbol"`); + await queryRunner.query(`DROP INDEX "IDX_tokens_chainId"`); + + // Drop foreign key constraint + await queryRunner.query(`ALTER TABLE "bridge_infos" DROP CONSTRAINT "FK_bridge_infos_tokenId"`); + + // Drop tables + await queryRunner.query(`DROP TABLE "bridge_infos"`); + await queryRunner.query(`DROP TABLE "tokens"`); + } +} diff --git a/backend-all/src/lib/database/migrations/1700000000002-CreateTransaction.ts b/backend-all/src/lib/database/migrations/1700000000002-CreateTransaction.ts new file mode 100644 index 0000000..c59559e --- /dev/null +++ b/backend-all/src/lib/database/migrations/1700000000002-CreateTransaction.ts @@ -0,0 +1,166 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CreateTransaction1700000000002 implements MigrationInterface { + name = 'CreateTransaction1700000000002' + + public async up(queryRunner: QueryRunner): Promise { + // Create transactions table + await queryRunner.query(` + CREATE TABLE "transactions" ( + "id" uuid NOT NULL DEFAULT uuid_generate_v4(), + "amount" text NOT NULL, + "timestamp" text NOT NULL, + "fromUser" character varying NOT NULL, + "toUser" character varying NOT NULL, + "fromChain" character varying NOT NULL, + "toChain" character varying NOT NULL, + "nonce" integer NOT NULL, + "symbol" character varying NOT NULL, + "fulfillAmount" text NOT NULL, + "fulfillFromChain" character varying NOT NULL, + "fulfillNonce" integer NOT NULL, + "fulfillFromUser" character varying NOT NULL, + "fulfillToUser" character varying NOT NULL, + "txBlock" text NOT NULL, + "confirmations" integer NOT NULL, + "fulfilled" boolean NOT NULL DEFAULT false, + "index" integer NOT NULL, + "userAddress" character varying NOT NULL, + "chainId" character varying NOT NULL, + "transactionHash" character varying NOT NULL, + "createdAt" TIMESTAMP NOT NULL DEFAULT now(), + "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), + CONSTRAINT "PK_transactions_id" PRIMARY KEY ("id") + ) + `); + + // Create indexes for better performance + await queryRunner.query(` + CREATE INDEX "IDX_transactions_userAddress" ON "transactions" ("userAddress") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_transactions_chainId" ON "transactions" ("chainId") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_transactions_fromUser" ON "transactions" ("fromUser") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_transactions_toUser" ON "transactions" ("toUser") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_transactions_nonce" ON "transactions" ("nonce") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_transactions_symbol" ON "transactions" ("symbol") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_transactions_fulfilled" ON "transactions" ("fulfilled") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_transactions_fromChain" ON "transactions" ("fromChain") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_transactions_toChain" ON "transactions" ("toChain") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_transactions_transactionHash" ON "transactions" ("transactionHash") + `); + + // Create composite indexes for common queries + await queryRunner.query(` + CREATE INDEX "IDX_transactions_userAddress_chainId" ON "transactions" ("userAddress", "chainId") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_transactions_fromUser_nonce" ON "transactions" ("fromUser", "nonce") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_transactions_fulfillFromUser_fulfillNonce" ON "transactions" ("fulfillFromUser", "fulfillNonce") + `); + + // Add check constraints for positive values + await queryRunner.query(` + ALTER TABLE "transactions" + ADD CONSTRAINT "CHK_transactions_nonce_positive" + CHECK ("nonce" >= 0) + `); + + await queryRunner.query(` + ALTER TABLE "transactions" + ADD CONSTRAINT "CHK_transactions_fulfillNonce_positive" + CHECK ("fulfillNonce" >= 0) + `); + + await queryRunner.query(` + ALTER TABLE "transactions" + ADD CONSTRAINT "CHK_transactions_confirmations_positive" + CHECK ("confirmations" >= 0) + `); + + await queryRunner.query(` + ALTER TABLE "transactions" + ADD CONSTRAINT "CHK_transactions_index_positive" + CHECK ("index" >= 0) + `); + + // Add check constraints for non-empty strings + await queryRunner.query(` + ALTER TABLE "transactions" + ADD CONSTRAINT "CHK_transactions_userAddress_not_empty" + CHECK (LENGTH("userAddress") > 0) + `); + + await queryRunner.query(` + ALTER TABLE "transactions" + ADD CONSTRAINT "CHK_transactions_chainId_not_empty" + CHECK (LENGTH("chainId") > 0) + `); + + await queryRunner.query(` + ALTER TABLE "transactions" + ADD CONSTRAINT "CHK_transactions_symbol_not_empty" + CHECK (LENGTH("symbol") > 0) + `); + } + + public async down(queryRunner: QueryRunner): Promise { + // Drop check constraints + await queryRunner.query(`ALTER TABLE "transactions" DROP CONSTRAINT "CHK_transactions_symbol_not_empty"`); + await queryRunner.query(`ALTER TABLE "transactions" DROP CONSTRAINT "CHK_transactions_chainId_not_empty"`); + await queryRunner.query(`ALTER TABLE "transactions" DROP CONSTRAINT "CHK_transactions_userAddress_not_empty"`); + await queryRunner.query(`ALTER TABLE "transactions" DROP CONSTRAINT "CHK_transactions_index_positive"`); + await queryRunner.query(`ALTER TABLE "transactions" DROP CONSTRAINT "CHK_transactions_confirmations_positive"`); + await queryRunner.query(`ALTER TABLE "transactions" DROP CONSTRAINT "CHK_transactions_fulfillNonce_positive"`); + await queryRunner.query(`ALTER TABLE "transactions" DROP CONSTRAINT "CHK_transactions_nonce_positive"`); + + // Drop composite indexes + await queryRunner.query(`DROP INDEX "IDX_transactions_fulfillFromUser_fulfillNonce"`); + await queryRunner.query(`DROP INDEX "IDX_transactions_fromUser_nonce"`); + await queryRunner.query(`DROP INDEX "IDX_transactions_userAddress_chainId"`); + + // Drop single column indexes + await queryRunner.query(`DROP INDEX "IDX_transactions_transactionHash"`); + await queryRunner.query(`DROP INDEX "IDX_transactions_toChain"`); + await queryRunner.query(`DROP INDEX "IDX_transactions_fromChain"`); + await queryRunner.query(`DROP INDEX "IDX_transactions_fulfilled"`); + await queryRunner.query(`DROP INDEX "IDX_transactions_symbol"`); + await queryRunner.query(`DROP INDEX "IDX_transactions_nonce"`); + await queryRunner.query(`DROP INDEX "IDX_transactions_toUser"`); + await queryRunner.query(`DROP INDEX "IDX_transactions_fromUser"`); + await queryRunner.query(`DROP INDEX "IDX_transactions_chainId"`); + await queryRunner.query(`DROP INDEX "IDX_transactions_userAddress"`); + + // Drop table + await queryRunner.query(`DROP TABLE "transactions"`); + } +} diff --git a/backend-all/src/lib/database/migrations/1700000000003-CreateBlockscanInfo.ts b/backend-all/src/lib/database/migrations/1700000000003-CreateBlockscanInfo.ts new file mode 100644 index 0000000..eb08867 --- /dev/null +++ b/backend-all/src/lib/database/migrations/1700000000003-CreateBlockscanInfo.ts @@ -0,0 +1,68 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CreateBlockscanInfo1700000000003 implements MigrationInterface { + name = 'CreateBlockscanInfo1700000000003' + + public async up(queryRunner: QueryRunner): Promise { + // Create blockscan_infos table + await queryRunner.query(` + CREATE TABLE "blockscan_infos" ( + "id" uuid NOT NULL DEFAULT uuid_generate_v4(), + "lastBlockScanned" text NOT NULL, + "chainId" character varying NOT NULL, + "contractAddress" character varying NOT NULL, + "createdAt" TIMESTAMP NOT NULL DEFAULT now(), + "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), + CONSTRAINT "PK_blockscan_infos_id" PRIMARY KEY ("id") + ) + `); + + // Create indexes for better performance + await queryRunner.query(` + CREATE INDEX "IDX_blockscan_infos_chainId" ON "blockscan_infos" ("chainId") + `); + + await queryRunner.query(` + CREATE INDEX "IDX_blockscan_infos_contractAddress" ON "blockscan_infos" ("contractAddress") + `); + + // Create composite index for unique chain + contract combinations + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_blockscan_infos_chainId_contractAddress" ON "blockscan_infos" ("chainId", "contractAddress") + `); + + // Add check constraints for non-empty strings + await queryRunner.query(` + ALTER TABLE "blockscan_infos" + ADD CONSTRAINT "CHK_blockscan_infos_chainId_not_empty" + CHECK (LENGTH("chainId") > 0) + `); + + await queryRunner.query(` + ALTER TABLE "blockscan_infos" + ADD CONSTRAINT "CHK_blockscan_infos_contractAddress_not_empty" + CHECK (LENGTH("contractAddress") > 0) + `); + + await queryRunner.query(` + ALTER TABLE "blockscan_infos" + ADD CONSTRAINT "CHK_blockscan_infos_lastBlockScanned_not_empty" + CHECK (LENGTH("lastBlockScanned") > 0) + `); + } + + public async down(queryRunner: QueryRunner): Promise { + // Drop check constraints + await queryRunner.query(`ALTER TABLE "blockscan_infos" DROP CONSTRAINT "CHK_blockscan_infos_lastBlockScanned_not_empty"`); + await queryRunner.query(`ALTER TABLE "blockscan_infos" DROP CONSTRAINT "CHK_blockscan_infos_contractAddress_not_empty"`); + await queryRunner.query(`ALTER TABLE "blockscan_infos" DROP CONSTRAINT "CHK_blockscan_infos_chainId_not_empty"`); + + // Drop indexes + await queryRunner.query(`DROP INDEX "IDX_blockscan_infos_chainId_contractAddress"`); + await queryRunner.query(`DROP INDEX "IDX_blockscan_infos_contractAddress"`); + await queryRunner.query(`DROP INDEX "IDX_blockscan_infos_chainId"`); + + // Drop table + await queryRunner.query(`DROP TABLE "blockscan_infos"`); + } +} diff --git a/backend-all/src/lib/database/migrations/1700000000004-CreateUserTransactionSync.ts b/backend-all/src/lib/database/migrations/1700000000004-CreateUserTransactionSync.ts new file mode 100644 index 0000000..2023645 --- /dev/null +++ b/backend-all/src/lib/database/migrations/1700000000004-CreateUserTransactionSync.ts @@ -0,0 +1,48 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CreateUserTransactionSync1700000000004 implements MigrationInterface { + name = 'CreateUserTransactionSync1700000000004' + + public async up(queryRunner: QueryRunner): Promise { + // Create user_transaction_syncs table + await queryRunner.query(` + CREATE TABLE "user_transaction_syncs" ( + "id" uuid NOT NULL DEFAULT uuid_generate_v4(), + "userAddress" character varying NOT NULL, + "synced" boolean NOT NULL DEFAULT false, + "createdAt" TIMESTAMP NOT NULL DEFAULT now(), + "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), + CONSTRAINT "PK_user_transaction_syncs_id" PRIMARY KEY ("id") + ) + `); + + // Create index for userAddress for better performance + await queryRunner.query(` + CREATE INDEX "IDX_user_transaction_syncs_userAddress" ON "user_transaction_syncs" ("userAddress") + `); + + // Create unique index for userAddress to ensure one record per user + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_user_transaction_syncs_userAddress_unique" ON "user_transaction_syncs" ("userAddress") + `); + + // Add check constraint for non-empty userAddress + await queryRunner.query(` + ALTER TABLE "user_transaction_syncs" + ADD CONSTRAINT "CHK_user_transaction_syncs_userAddress_not_empty" + CHECK (LENGTH("userAddress") > 0) + `); + } + + public async down(queryRunner: QueryRunner): Promise { + // Drop check constraints + await queryRunner.query(`ALTER TABLE "user_transaction_syncs" DROP CONSTRAINT "CHK_user_transaction_syncs_userAddress_not_empty"`); + + // Drop indexes + await queryRunner.query(`DROP INDEX "IDX_user_transaction_syncs_userAddress_unique"`); + await queryRunner.query(`DROP INDEX "IDX_user_transaction_syncs_userAddress"`); + + // Drop table + await queryRunner.query(`DROP TABLE "user_transaction_syncs"`); + } +} diff --git a/backend-all/src/lib/database/migrations/1700000000005-AddTransactionDateToTransaction.ts b/backend-all/src/lib/database/migrations/1700000000005-AddTransactionDateToTransaction.ts new file mode 100644 index 0000000..c4939ba --- /dev/null +++ b/backend-all/src/lib/database/migrations/1700000000005-AddTransactionDateToTransaction.ts @@ -0,0 +1,26 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddTransactionDateToTransaction1700000000005 implements MigrationInterface { + name = 'AddTransactionDateToTransaction1700000000005' + + public async up(queryRunner: QueryRunner): Promise { + // Add transactionDate column to transactions table + await queryRunner.query(` + ALTER TABLE "transactions" + ADD COLUMN "transactionDate" TIMESTAMP + `); + + // Create index for transactionDate for better performance + await queryRunner.query(` + CREATE INDEX "IDX_transactions_transactionDate" ON "transactions" ("transactionDate") + `); + } + + public async down(queryRunner: QueryRunner): Promise { + // Drop index + await queryRunner.query(`DROP INDEX "IDX_transactions_transactionDate"`); + + // Drop column + await queryRunner.query(`ALTER TABLE "transactions" DROP COLUMN "transactionDate"`); + } +} diff --git a/backend-all/src/lib/database/migrations/1700000000006-AddBridgeInfoRelationToTransaction.ts b/backend-all/src/lib/database/migrations/1700000000006-AddBridgeInfoRelationToTransaction.ts new file mode 100644 index 0000000..db8627c --- /dev/null +++ b/backend-all/src/lib/database/migrations/1700000000006-AddBridgeInfoRelationToTransaction.ts @@ -0,0 +1,38 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddBridgeInfoRelationToTransaction1700000000006 implements MigrationInterface { + name = 'AddBridgeInfoRelationToTransaction1700000000006' + + public async up(queryRunner: QueryRunner): Promise { + // Add bridgeInfoId column to transactions table + await queryRunner.query(` + ALTER TABLE "transactions" + ADD COLUMN "bridgeInfoId" uuid + `); + + // Create foreign key constraint + await queryRunner.query(` + ALTER TABLE "transactions" + ADD CONSTRAINT "FK_transactions_bridgeInfoId" + FOREIGN KEY ("bridgeInfoId") + REFERENCES "bridge_infos"("id") + ON DELETE SET NULL ON UPDATE NO ACTION + `); + + // Create index for bridgeInfoId for better performance + await queryRunner.query(` + CREATE INDEX "IDX_transactions_bridgeInfoId" ON "transactions" ("bridgeInfoId") + `); + } + + public async down(queryRunner: QueryRunner): Promise { + // Drop index + await queryRunner.query(`DROP INDEX "IDX_transactions_bridgeInfoId"`); + + // Drop foreign key constraint + await queryRunner.query(`ALTER TABLE "transactions" DROP CONSTRAINT "FK_transactions_bridgeInfoId"`); + + // Drop column + await queryRunner.query(`ALTER TABLE "transactions" DROP COLUMN "bridgeInfoId"`); + } +} diff --git a/backend-all/src/lib/database/migrations/1700000000007-MakeTransactionHashNullable.ts b/backend-all/src/lib/database/migrations/1700000000007-MakeTransactionHashNullable.ts new file mode 100644 index 0000000..52620a1 --- /dev/null +++ b/backend-all/src/lib/database/migrations/1700000000007-MakeTransactionHashNullable.ts @@ -0,0 +1,21 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class MakeTransactionHashNullable1700000000007 implements MigrationInterface { + name = 'MakeTransactionHashNullable1700000000007' + + public async up(queryRunner: QueryRunner): Promise { + // Make transactionHash column nullable + await queryRunner.query(` + ALTER TABLE "transactions" + ALTER COLUMN "transactionHash" DROP NOT NULL + `); + } + + public async down(queryRunner: QueryRunner): Promise { + // Make transactionHash column NOT NULL again + await queryRunner.query(` + ALTER TABLE "transactions" + ALTER COLUMN "transactionHash" SET NOT NULL + `); + } +} diff --git a/backend-all/src/lib/database/migrations/1700000000008-AddChainTypeToUserTransactionSync.ts b/backend-all/src/lib/database/migrations/1700000000008-AddChainTypeToUserTransactionSync.ts new file mode 100644 index 0000000..a53a0a3 --- /dev/null +++ b/backend-all/src/lib/database/migrations/1700000000008-AddChainTypeToUserTransactionSync.ts @@ -0,0 +1,44 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddChainTypeToUserTransactionSync1700000000008 implements MigrationInterface { + name = 'AddChainTypeToUserTransactionSync1700000000008' + + public async up(queryRunner: QueryRunner): Promise { + // Add chainType column to user_transaction_syncs table + await queryRunner.query(` + ALTER TABLE "user_transaction_syncs" + ADD COLUMN "chainType" character varying NOT NULL DEFAULT 'EVM' + `); + + // Create index for chainType for better performance + await queryRunner.query(` + CREATE INDEX "IDX_user_transaction_syncs_chainType" ON "user_transaction_syncs" ("chainType") + `); + + // Create composite index for userAddress and chainType (non-unique) + await queryRunner.query(` + CREATE INDEX "IDX_user_transaction_syncs_userAddress_chainType" ON "user_transaction_syncs" ("userAddress", "chainType") + `); + + // Drop the old unique index on userAddress only + await queryRunner.query(` + DROP INDEX "IDX_user_transaction_syncs_userAddress_unique" + `); + } + + public async down(queryRunner: QueryRunner): Promise { + // Drop composite index + await queryRunner.query(`DROP INDEX "IDX_user_transaction_syncs_userAddress_chainType"`); + + // Drop chainType index + await queryRunner.query(`DROP INDEX "IDX_user_transaction_syncs_chainType"`); + + // Restore the old unique index on userAddress only + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_user_transaction_syncs_userAddress_unique" ON "user_transaction_syncs" ("userAddress") + `); + + // Drop chainType column + await queryRunner.query(`ALTER TABLE "user_transaction_syncs" DROP COLUMN "chainType"`); + } +} diff --git a/backend-all/src/lib/database/migrations/1700000000009-AddClaimTransactionToTransaction.ts b/backend-all/src/lib/database/migrations/1700000000009-AddClaimTransactionToTransaction.ts new file mode 100644 index 0000000..e416f61 --- /dev/null +++ b/backend-all/src/lib/database/migrations/1700000000009-AddClaimTransactionToTransaction.ts @@ -0,0 +1,18 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddClaimTransactionToTransaction1700000000009 implements MigrationInterface { + name = 'AddClaimTransactionToTransaction1700000000009' + + public async up(queryRunner: QueryRunner): Promise { + // Add claimTransactionHash column to transactions table + await queryRunner.query(` + ALTER TABLE "transactions" + ADD COLUMN "claimTransactionHash" character varying + `); + } + + public async down(queryRunner: QueryRunner): Promise { + // Drop claimTransactionHash column + await queryRunner.query(`ALTER TABLE "transactions" DROP COLUMN "claimTransactionHash"`); + } +} diff --git a/backend-all/src/lib/database/repositories/BlockscanInfoRepository.ts b/backend-all/src/lib/database/repositories/BlockscanInfoRepository.ts new file mode 100644 index 0000000..8177a67 --- /dev/null +++ b/backend-all/src/lib/database/repositories/BlockscanInfoRepository.ts @@ -0,0 +1,191 @@ +import { FindOptionsWhere, Repository } from "typeorm"; +import { BlockscanInfo } from "../entities/BlockscanInfo"; +import { AppDataSource } from "../data-source"; + +export class BlockscanInfoRepository { + private repository: Repository; + + constructor() { + this.repository = AppDataSource.getRepository(BlockscanInfo); + } + + async findOne(where: FindOptionsWhere) { + return this.repository.findOne({ + where + }); + } + + async find(where: FindOptionsWhere) { + return this.repository.find({ + where + }); + } + + async findAll() { + return this.repository.find(); + } + + async findById(id: string) { + return this.repository.findOne({ + where: { id } + }); + } + + async findByChainId(chainId: string) { + return this.repository.find({ + where: { chainId } + }); + } + + async findByContractAddress(contractAddress: string) { + return this.repository.find({ + where: { contractAddress } + }); + } + + async findByChainIdAndContractAddress(chainId: string, contractAddress: string) { + return this.repository.findOne({ + where: { chainId, contractAddress } + }); + } + + async create(blockscanInfoData: Partial) { + const blockscanInfo = this.repository.create(blockscanInfoData); + return blockscanInfo; + } + + async save(blockscanInfo: BlockscanInfo) { + return await this.repository.save(blockscanInfo); + } + + async update(id: string, blockscanInfoData: Partial) { + await this.repository.update(id, blockscanInfoData); + return this.findById(id); + } + + async updateByChainIdAndContractAddress(chainId: string, contractAddress: string, blockscanInfoData: Partial) { + await this.repository.update({ chainId, contractAddress }, blockscanInfoData); + return this.findByChainIdAndContractAddress(chainId, contractAddress); + } + + async updateLastBlockScanned(chainId: string, contractAddress: string, lastBlockScanned: string) { + await this.repository.update({ chainId, contractAddress }, { lastBlockScanned }); + return this.findByChainIdAndContractAddress(chainId, contractAddress); + } + + async delete(id: string) { + const result = await this.repository.delete(id); + return result.affected !== undefined && result.affected !== null && result.affected > 0; + } + + async deleteByChainIdAndContractAddress(chainId: string, contractAddress: string) { + const result = await this.repository.delete({ chainId, contractAddress }); + return result.affected !== undefined && result.affected !== null && result.affected > 0; + } + + async deleteByChainId(chainId: string) { + const result = await this.repository.delete({ chainId }); + return result.affected !== undefined && result.affected !== null && result.affected > 0; + } + + async deleteByContractAddress(contractAddress: string) { + const result = await this.repository.delete({ contractAddress }); + return result.affected !== undefined && result.affected !== null && result.affected > 0; + } + + async findBlockscanInfosByChain(chainId: string) { + return this.repository.find({ + where: { chainId } + }); + } + + async findBlockscanInfosByContract(contractAddress: string) { + return this.repository.find({ + where: { contractAddress } + }); + } + + async countByChainId(chainId: string) { + return this.repository.count({ where: { chainId } }); + } + + async countByContractAddress(contractAddress: string) { + return this.repository.count({ where: { contractAddress } }); + } + + async countAll() { + return this.repository.count(); + } + + async existsByChainIdAndContractAddress(chainId: string, contractAddress: string) { + const count = await this.repository.count({ where: { chainId, contractAddress } }); + return count > 0; + } + + async existsByChainId(chainId: string) { + const count = await this.repository.count({ where: { chainId } }); + return count > 0; + } + + async existsByContractAddress(contractAddress: string) { + const count = await this.repository.count({ where: { contractAddress } }); + return count > 0; + } + + async findBlockscanInfosWithPagination(offset: number, limit: number) { + return this.repository.find({ + skip: offset, + take: limit, + order: { updatedAt: 'DESC' } + }); + } + + async findBlockscanInfosByChainWithPagination(chainId: string, offset: number, limit: number) { + return this.repository.find({ + where: { chainId }, + skip: offset, + take: limit, + order: { updatedAt: 'DESC' } + }); + } + + async upsertByChainIdAndContractAddress(chainId: string, contractAddress: string, blockscanInfoData: Partial) { + const existing = await this.findByChainIdAndContractAddress(chainId, contractAddress); + + if (existing) { + return this.updateByChainIdAndContractAddress(chainId, contractAddress, blockscanInfoData); + } else { + const newData = { ...blockscanInfoData, chainId, contractAddress }; + const newBlockscanInfo = this.repository.create(newData); + return this.save(newBlockscanInfo); + } + } + + async getLatestBlockForChainAndContract(chainId: string, contractAddress: string) { + const blockscanInfo = await this.findByChainIdAndContractAddress(chainId, contractAddress); + return blockscanInfo?.lastBlockScanned || "0"; + } + + async getAllChains() { + return this.repository + .createQueryBuilder("blockscanInfo") + .select("DISTINCT blockscanInfo.chainId", "chainId") + .getRawMany(); + } + + async getAllContractAddresses() { + return this.repository + .createQueryBuilder("blockscanInfo") + .select("DISTINCT blockscanInfo.contractAddress", "contractAddress") + .getRawMany(); + } + + async getAllChainAndContractCombinations() { + return this.repository + .createQueryBuilder("blockscanInfo") + .select("blockscanInfo.chainId", "chainId") + .addSelect("blockscanInfo.contractAddress", "contractAddress") + .addSelect("blockscanInfo.lastBlockScanned", "lastBlockScanned") + .getRawMany(); + } +} diff --git a/backend-all/src/lib/database/repositories/BridgeInfoRepository.ts b/backend-all/src/lib/database/repositories/BridgeInfoRepository.ts new file mode 100644 index 0000000..730dbe3 --- /dev/null +++ b/backend-all/src/lib/database/repositories/BridgeInfoRepository.ts @@ -0,0 +1,126 @@ +import { FindOptionsWhere, Repository } from "typeorm"; +import { BridgeInfo } from "../entities/BridgeInfo"; +import { AppDataSource } from "../data-source"; + +export class BridgeInfoRepository { + private repository: Repository; + + constructor() { + this.repository = AppDataSource.getRepository(BridgeInfo); + } + + async findOne(where: FindOptionsWhere) { + return this.repository.findOne({ + where, + relations: ["token"] + }); + } + + async find(where: FindOptionsWhere) { + return this.repository.find({ + where, + relations: ["token"] + }); + } + + async findAll() { + return this.repository.find({ + relations: ["token"] + }); + } + + async findById(id: string) { + return this.repository.findOne({ + where: { id }, + relations: ["token"] + }); + } + + async findByBridgeAddress(bridgeAddress: string) { + return this.repository.findOne({ + where: { bridgeAddress }, + relations: ["token"] + }); + } + + async findByChainId(chainId: string) { + return this.repository.find({ + where: { chainId }, + relations: ["token"] + }); + } + + async findByTokenId(tokenId: string) { + return this.repository.find({ + where: { tokenId }, + relations: ["token"] + }); + } + + async findByTokenAddress(tokenAddress: string) { + return this.repository + .createQueryBuilder("bridgeInfo") + .leftJoinAndSelect("bridgeInfo.token", "token") + .where("token.tokenAddress = :tokenAddress", { tokenAddress }) + .getMany(); + } + + create(bridgeInfoData: Partial) { + const bridgeInfo = this.repository.create(bridgeInfoData); + return bridgeInfo; + } + + async save(bridgeInfo: BridgeInfo) { + return this.repository.save(bridgeInfo); + } + + async update(id: string, bridgeInfoData: Partial) { + await this.repository.update(id, bridgeInfoData); + return this.findById(id); + } + + async updateByBridgeAddress(bridgeAddress: string, bridgeInfoData: Partial) { + await this.repository.update({ bridgeAddress }, bridgeInfoData); + return this.findByBridgeAddress(bridgeAddress); + } + + async delete(id: string) { + const result = await this.repository.delete(id); + return result.affected !== undefined && result.affected !== null && result.affected > 0; + } + + async deleteByBridgeAddress(bridgeAddress: string) { + const result = await this.repository.delete({ bridgeAddress }); + return result.affected !== undefined && result.affected !== null && result.affected > 0; + } + + async findBridgeInfosByChainAndToken(chainId: string, tokenId: string) { + return this.repository.find({ + where: { chainId, tokenId }, + relations: ["token"] + }); + } + + async existsByBridgeAddress(bridgeAddress: string) { + const count = await this.repository.count({ where: { bridgeAddress } }); + return count > 0; + } + + async findBridgesWithTokenDetails() { + return this.repository + .createQueryBuilder("bridgeInfo") + .leftJoinAndSelect("bridgeInfo.token", "token") + .orderBy("bridgeInfo.createdAt", "DESC") + .getMany(); + } + + async updateFees(bridgeAddress: string, fees: { feeFulfill: number; feeSend: number }) { + await this.repository.update({ bridgeAddress }, { fees }); + return this.findByBridgeAddress(bridgeAddress); + } + + async updateLimitPerSend(bridgeAddress: string, limitPerSend: string) { + await this.repository.update({ bridgeAddress }, { limitPerSend }); + return this.findByBridgeAddress(bridgeAddress); + } +} diff --git a/backend-all/src/lib/database/repositories/TokenRepository.ts b/backend-all/src/lib/database/repositories/TokenRepository.ts new file mode 100644 index 0000000..8e573b4 --- /dev/null +++ b/backend-all/src/lib/database/repositories/TokenRepository.ts @@ -0,0 +1,109 @@ +import { FindOptionsWhere, Repository } from "typeorm"; +import { Token } from "../entities/Token"; +import { AppDataSource } from "../data-source"; + +export class TokenRepository { + private repository: Repository; + + constructor() { + this.repository = AppDataSource.getRepository(Token); + } + + async findOne(where: FindOptionsWhere) { + return this.repository.findOne({ + where, + relations: ["bridgeInfos"] + }); + } + + async find(where: FindOptionsWhere) { + return this.repository.find({ + where, + relations: ["bridgeInfos"] + }); + } + + async findAll() { + return this.repository.find({ + relations: ["bridgeInfos"] + }); + } + + async findById(id: string) { + return this.repository.findOne({ + where: { id }, + relations: ["bridgeInfos"] + }); + } + + async findByTokenAddress(tokenAddress: string) { + return this.repository.findOne({ + where: { tokenAddress }, + relations: ["bridgeInfos"] + }); + } + + + + async findByChainId(chainId: string) { + return this.repository.find({ + where: { chainId }, + relations: ["bridgeInfos"] + }); + } + + async findBySymbol(symbol: string) { + return this.repository.find({ + where: { symbol }, + relations: ["bridgeInfos"] + }); + } + + async findByName(name: string) { + return this.repository.findOne({ + where: { name }, + relations: ["bridgeInfos"] + }); + } + + async create(tokenData: Partial) { + const token = this.repository.create(tokenData); + return token; + } + + async save(token: Token) { + return await this.repository.save(token); + } + + async update(id: string, tokenData: Partial) { + await this.repository.update(id, tokenData); + return this.findById(id); + } + + async updateByTokenAddress(tokenAddress: string, tokenData: Partial) { + await this.repository.update({ tokenAddress }, tokenData); + return this.findByTokenAddress(tokenAddress); + } + + async delete(id: string) { + const result = await this.repository.delete(id); + return result.affected !== undefined && result.affected !== null && result.affected > 0; + } + + async deleteByTokenAddress(tokenAddress: string) { + const result = await this.repository.delete({ tokenAddress }); + return result.affected !== undefined && result.affected !== null && result.affected > 0; + } + + async findTokensByChainAndSymbol(chainId: string, symbol: string) { + return this.repository.find({ + where: { chainId, symbol }, + relations: ["bridgeInfos"] + }); + } + + async existsByTokenAddress(tokenAddress: string) { + const count = await this.repository.count({ where: { tokenAddress } }); + return count > 0; + } +} diff --git a/backend-all/src/lib/database/repositories/TransactionRepository.ts b/backend-all/src/lib/database/repositories/TransactionRepository.ts new file mode 100644 index 0000000..6a7820d --- /dev/null +++ b/backend-all/src/lib/database/repositories/TransactionRepository.ts @@ -0,0 +1,352 @@ +import { DeepPartial, FindOptionsWhere, In, Repository } from 'typeorm' +import { Transaction } from '../entities/Transaction' +import { AppDataSource } from '../data-source' + +export class TransactionRepository { + private repository: Repository + + constructor() { + this.repository = AppDataSource.getRepository(Transaction) + } + + async findOne(where: FindOptionsWhere) { + return this.repository.findOne({ + where, + }) + } + + async find(where: FindOptionsWhere) { + return this.repository.find({ + where, + }) + } + + async findAll() { + return this.repository.find() + } + + async findById(id: string) { + return this.repository.findOne({ + where: { id }, + }) + } + + async findByUserAddress(userAddress: string) { + return this.repository.find({ + where: { userAddress }, + }) + } + + async findByUserAddressAndChainId(userAddress: string, chainId: string) { + return this.repository.find({ + where: { userAddress, chainId }, + }) + } + + async findByFromUser(fromUser: string) { + return this.repository.find({ + where: { fromUser }, + }) + } + + async findByToUser(toUser: string) { + return this.repository.find({ + where: { toUser }, + }) + } + + async findByNonce(nonce: number) { + return this.repository.find({ + where: { nonce }, + }) + } + + async findByFromUserAndNonce(fromUser: string, nonce: number) { + return this.repository.findOne({ + where: { fromUser, nonce }, + }) + } + + async findByFulfillFromUserAndFulfillNonce( + fulfillFromUser: string, + fulfillNonce: number + ) { + return this.repository.findOne({ + where: { fulfillFromUser, fulfillNonce }, + }) + } + + async findBySymbol(symbol: string) { + return this.repository.find({ + where: { symbol }, + }) + } + + async findByFulfilled(fulfilled: boolean) { + return this.repository.find({ + where: { fulfilled }, + }) + } + + async findByFromChain(fromChain: string) { + return this.repository.find({ + where: { fromChain }, + }) + } + + async findByToChain(toChain: string) { + return this.repository.find({ + where: { toChain }, + }) + } + + async findByChainId(chainId: string) { + return this.repository.find({ + where: { chainId }, + }) + } + + async findByIndex(index: number) { + return this.repository.find({ + where: { index }, + }) + } + + async findByTransactionHash(transactionHash: string) { + return this.repository.findOne({ + where: { transactionHash }, + }) + } + + create(transactionData: Partial) { + const transaction = this.repository.create(transactionData) + return transaction + } + + async save(transaction: DeepPartial) { + return await this.repository.save(transaction) + } + + async insert(transaction: Transaction[]) { + return await this.repository.insert(transaction) + } + + async update(id: string, transactionData: Partial) { + await this.repository.update(id, transactionData) + return this.findById(id) + } + + async updateByFromUserAndNonce( + fromUser: string, + nonce: number, + transactionData: Partial + ) { + await this.repository.update({ fromUser, nonce }, transactionData) + return this.findByFromUserAndNonce(fromUser, nonce) + } + + async updateByFulfillFromUserAndFulfillNonce( + fulfillFromUser: string, + fulfillNonce: number, + transactionData: Partial + ) { + await this.repository.update({ fulfillFromUser, fulfillNonce }, transactionData) + return this.findByFulfillFromUserAndFulfillNonce(fulfillFromUser, fulfillNonce) + } + + async updateByTransactionHash( + transactionHash: string, + transactionData: Partial + ) { + await this.repository.update({ transactionHash }, transactionData) + return this.findByTransactionHash(transactionHash) + } + + async delete(id: string) { + const result = await this.repository.delete(id) + return ( + result.affected !== undefined && result.affected !== null && result.affected > 0 + ) + } + + async deleteByFromUserAndNonce(fromUser: string, nonce: number) { + const result = await this.repository.delete({ fromUser, nonce }) + return ( + result.affected !== undefined && result.affected !== null && result.affected > 0 + ) + } + + async deleteByFulfillFromUserAndFulfillNonce( + fulfillFromUser: string, + fulfillNonce: number + ) { + const result = await this.repository.delete({ fulfillFromUser, fulfillNonce }) + return ( + result.affected !== undefined && result.affected !== null && result.affected > 0 + ) + } + + async deleteByTransactionHash(transactionHash: string) { + const result = await this.repository.delete({ transactionHash }) + return ( + result.affected !== undefined && result.affected !== null && result.affected > 0 + ) + } + + async findTransactionsByUserAndChain(userAddress: string, chainId: string) { + return this.repository.find({ + where: { userAddress, chainId }, + }) + } + + async findTransactionsBySymbolAndChain(symbol: string, chainId: string) { + return this.repository.find({ + where: { symbol, chainId }, + }) + } + + async findUnfulfilledTransactions() { + return this.repository.find({ + where: { fulfilled: false }, + }) + } + + async findFulfilledTransactions() { + return this.repository.find({ + where: { fulfilled: true }, + }) + } + + async findTransactionsByTimeRange(startTime: string, endTime: string) { + return this.repository + .createQueryBuilder('transaction') + .where('transaction.timestamp >= :startTime', { startTime }) + .andWhere('transaction.timestamp <= :endTime', { endTime }) + .getMany() + } + + async findTransactionsByAmountRange(minAmount: string, maxAmount: string) { + return this.repository + .createQueryBuilder('transaction') + .where('CAST(transaction.amount AS NUMERIC) >= CAST(:minAmount AS NUMERIC)', { + minAmount, + }) + .andWhere('CAST(transaction.amount AS NUMERIC) <= CAST(:maxAmount AS NUMERIC)', { + maxAmount, + }) + .getMany() + } + + async countByUserAddress(userAddress: string) { + return this.repository.count({ where: { userAddress } }) + } + + async countByChainId(chainId: string) { + return this.repository.count({ where: { chainId } }) + } + + async countBySymbol(symbol: string) { + return this.repository.count({ where: { symbol } }) + } + + async countByFulfilled(fulfilled: boolean) { + return this.repository.count({ where: { fulfilled } }) + } + + async existsByFromUserAndNonce(fromUser: string, nonce: number) { + const count = await this.repository.count({ where: { fromUser, nonce } }) + return count > 0 + } + + async existsByFulfillFromUserAndFulfillNonce( + fulfillFromUser: string, + fulfillNonce: number + ) { + const count = await this.repository.count({ + where: { fulfillFromUser, fulfillNonce }, + }) + return count > 0 + } + + async existsByTransactionHash(transactionHash: string) { + const count = await this.repository.count({ where: { transactionHash } }) + return count > 0 + } + + async findTransactionsWithPagination(offset: number, limit: number) { + return this.repository.find({ + skip: offset, + take: limit, + order: { createdAt: 'DESC' }, + }) + } + + async findTransactionsByUserWithPagination( + userAddress: string, + options: { page: number; limit: number }, + chainIds?: string[], + fulfilled?: boolean, + symbol?: string, + secondaryAddress?: string + ) { + let { page, limit } = options + page = +page + limit = +limit + const skip = (page - 1) * limit + + let addresses = [userAddress] + + if (secondaryAddress){ + addresses.push(secondaryAddress) + } + + let whereCondition: any = { userAddress: In(addresses) } + if (chainIds && chainIds.length > 0) { + whereCondition.chainId = In(chainIds) + } + if (fulfilled !== undefined) { + whereCondition.fulfilled = fulfilled + } + if (symbol) { + if (symbol === 'XRWA'){ + symbol = 'RWA' + } + whereCondition.symbol = symbol + } + // console.log('whereCondition', whereCondition) + + // Get total count for pagination metadata + const totalCount = await this.repository.count({ + where: whereCondition, + }) + + // Get paginated items + const items = await this.repository.find({ + where: { + ...whereCondition, + }, + skip: skip, + take: limit, + order: { transactionHash: 'DESC' }, + }) + + // Calculate pagination metadata + const totalPages = Math.ceil(totalCount / limit) + const hasNextPage = page < totalPages + const hasPreviousPage = page > 1 + + return { + items, + pagination: { + page, + limit, + totalCount, + totalPages, + hasNextPage, + hasPreviousPage, + nextPage: hasNextPage ? page + 1 : null, + previousPage: hasPreviousPage ? page - 1 : null, + }, + } + } +} diff --git a/backend-all/src/lib/database/repositories/UserTransactionSyncRepository.ts b/backend-all/src/lib/database/repositories/UserTransactionSyncRepository.ts new file mode 100644 index 0000000..fdd6e77 --- /dev/null +++ b/backend-all/src/lib/database/repositories/UserTransactionSyncRepository.ts @@ -0,0 +1,29 @@ +import { FindOptionsWhere, Repository } from "typeorm"; +import { UserTransactionSync } from "../entities/UserTransactionSync"; +import { AppDataSource } from "../data-source"; + +export class UserTransactionSyncRepository { + private repository: Repository; + + constructor() { + this.repository = AppDataSource.getRepository(UserTransactionSync); + } + + async findOne(where: FindOptionsWhere) { + return this.repository.findOne({ + where + }); + } + + create(userTransactionSync: Partial) { + return this.repository.create(userTransactionSync); + } + + async save(userTransactionSync: UserTransactionSync) { + return this.repository.save(userTransactionSync); + } + + async insert(userTransactionSync: UserTransactionSync[]) { + return this.repository.insert(userTransactionSync); + } +} diff --git a/backend-all/src/lib/database/repositories/index.ts b/backend-all/src/lib/database/repositories/index.ts new file mode 100644 index 0000000..2a3d6bf --- /dev/null +++ b/backend-all/src/lib/database/repositories/index.ts @@ -0,0 +1,16 @@ +// Export all repositories here +import {TokenRepository} from './TokenRepository' +import {BridgeInfoRepository} from './BridgeInfoRepository' +import {TransactionRepository} from './TransactionRepository' +import {BlockscanInfoRepository} from './BlockscanInfoRepository' +import {UserTransactionSyncRepository} from './UserTransactionSyncRepository' + +const tokenRepo = new TokenRepository() +const bridgeInfoRepo = new BridgeInfoRepository() +const transactionRepo = new TransactionRepository() +const blockscanInfoRepo = new BlockscanInfoRepository() +const userTransactionSyncRepo = new UserTransactionSyncRepository() + + +// Add your repository exports as you create them +export { tokenRepo, bridgeInfoRepo, transactionRepo, blockscanInfoRepo, userTransactionSyncRepo } \ No newline at end of file diff --git a/backend-all/src/lib/database/seeders/index.ts b/backend-all/src/lib/database/seeders/index.ts new file mode 100644 index 0000000..745c8c3 --- /dev/null +++ b/backend-all/src/lib/database/seeders/index.ts @@ -0,0 +1,40 @@ +import { ChainId } from '@/gotbit-tools/node/types' +import EventLogger from '@/lib/logger/index.logger' +import { bridgeService, tokenService } from '@/services' +import { BRIDGEASSISTS } from '@/utils/constant' +import { _getProvider } from '@/utils/helpers' + +export async function seedTokenAndBridges() { + const chainIds = Object.keys(BRIDGEASSISTS) + + await Promise.all( + chainIds.map(async (chainId) => { + try { + const provider = await _getProvider(chainId as any) + const bridgeAssists: { bridgeAssist: string; token: string }[] = ( + BRIDGEASSISTS as any + )[chainId] + + for (let bridgeAssist of bridgeAssists) { + EventLogger.info(`Seeding token ${bridgeAssist.token} on ${chainId}`) + const token = await tokenService.addToken( + bridgeAssist.token, + chainId as ChainId, + provider + ) + + const bridge = await bridgeService.addBridge( + bridgeAssist.bridgeAssist, + chainId as ChainId, + token, + provider + ) + EventLogger.info(`Done Seeding token ${bridgeAssist.token} on ${chainId}`) + } + EventLogger.info(`Done Seeding tokens on ${chainId}`) + } catch (error: any) { + EventLogger.error(`Error seeding for ${chainId} ${error.message}`) + } + }) + ) +} diff --git a/backend-all/src/lib/database/subscribers/.gitkeep b/backend-all/src/lib/database/subscribers/.gitkeep new file mode 100644 index 0000000..d3a5cf6 --- /dev/null +++ b/backend-all/src/lib/database/subscribers/.gitkeep @@ -0,0 +1,2 @@ +# This file ensures the subscribers directory is tracked by git +# TypeORM subscribers will be placed here diff --git a/backend-all/src/lib/logger/index.logger.ts b/backend-all/src/lib/logger/index.logger.ts new file mode 100644 index 0000000..caaa5cc --- /dev/null +++ b/backend-all/src/lib/logger/index.logger.ts @@ -0,0 +1,23 @@ +import Logger from './logger'; + +export default class EventLogger { + public static error(message: string) { + Logger.error(`${message}`); + } + + public static warn(message: string) { + Logger.warn(`${message}`); + } + + public static info(message: string) { + Logger.info(`${message}`); + } + + public static http(message: string) { + Logger.http(`${message}`); + } + + public static debug(message: string) { + Logger.debug(`${message}`); + } +} diff --git a/backend-all/src/lib/logger/logger.ts b/backend-all/src/lib/logger/logger.ts new file mode 100644 index 0000000..8a4362e --- /dev/null +++ b/backend-all/src/lib/logger/logger.ts @@ -0,0 +1,27 @@ +import { createLogger, transports, format } from 'winston'; + +const logLevel = 'info'; + + +const winstonFormatConsole = format.combine( + format.colorize({ + all: true, + }), + format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss:ms' }), + format.align(), + format.printf( + (info) => + `[timestamp : ${info.timestamp as any}] [level: ${info.level}] : ${info.message as string}`, + ), +); + +export default createLogger({ + // format: winstonFormatFile, + level: 'warn', + transports: [ + new transports.Console({ + level: logLevel, + format: winstonFormatConsole, + }), + ], +}); diff --git a/backend-all/src/routes/bridges/index.ts b/backend-all/src/routes/bridges/index.ts new file mode 100644 index 0000000..b43368a --- /dev/null +++ b/backend-all/src/routes/bridges/index.ts @@ -0,0 +1,19 @@ +import { type Request } from 'express' +import type { Resource } from 'express-automatic-routes' +import { bridgeService} from '@/services' +// import axios from 'axios' + +export default (): Resource => ({ + async get(req: Request<{}, {}, {}, {}>, res) { + try { + + const response = await bridgeService.getAllBridges() + res.status(200).json({ + success: true, + data: response, + }) + } catch (error: any) { + res.status(400).json({ error: error.message }) + } + }, +}) diff --git a/backend-all/src/routes/seed-tokens.ts b/backend-all/src/routes/seed-tokens.ts new file mode 100644 index 0000000..ec335aa --- /dev/null +++ b/backend-all/src/routes/seed-tokens.ts @@ -0,0 +1,16 @@ +import { type Request } from 'express' +import type { Resource } from 'express-automatic-routes' +import { tokenService } from '@/services' +// import axios from 'axios' + +export default (): Resource => ({ + async get(req: Request<{}, {}, {}, {}>, res) { + try { + + const response = await tokenService.seedTokenAndBridges() + res.status(200).json(response) + } catch (error: any) { + res.status(400).json({ error: error.message }) + } + }, +}) diff --git a/backend-all/src/routes/sign-solana-evm.ts b/backend-all/src/routes/sign-solana-evm.ts index e4fa411..ce367cb 100644 --- a/backend-all/src/routes/sign-solana-evm.ts +++ b/backend-all/src/routes/sign-solana-evm.ts @@ -3,13 +3,21 @@ import type { Resource } from 'express-automatic-routes' import { signSolanaToEvm } from '@/services/blockchain' import { GetTransactionSignationDto } from '@/types' +import EventLogger from '@/lib/logger/index.logger' // import axios from 'axios' export default (): Resource => ({ async get(req: Request<{}, {}, {}, GetTransactionSignationDto>, res) { try { - - const { fromBridgeAddress, toBridgeAssistAddress, fromChain, fromUser, index, _tokenMint } = req.query + const { + fromBridgeAddress, + toBridgeAssistAddress, + fromChain, + fromUser, + index, + transactionId, + tokenMint, + } = req.query if (!fromBridgeAddress) return res.status(400).send('fromBridgeAddress not specified') @@ -18,8 +26,8 @@ export default (): Resource => ({ if (!fromChain) return res.status(400).send('from chain not specified') if (!fromUser) return res.status(400).send('from user not specified') if (!index) return res.status(400).send('index not specified') - if (!_tokenMint) return res.status(400).send('token mint not specified') - + if (!transactionId) return res.status(400).send('transactionId not specified') + if (!tokenMint) return res.status(400).send('tokenMint not specified') const signature = await signSolanaToEvm( req, fromChain, @@ -27,12 +35,13 @@ export default (): Resource => ({ toBridgeAssistAddress, fromUser, index, - _tokenMint + tokenMint, + transactionId ) - res.status(200).json({signature}) + res.status(200).json({ signature }) } catch (error: any) { - console.log(error, 'error') + EventLogger.error(`Error during sign solana to evm: ${error.message}`) res.status(400).json({ error: error.message }) } }, diff --git a/backend-all/src/routes/sign-solana.ts b/backend-all/src/routes/sign-solana.ts index ef6b79b..fc4c327 100644 --- a/backend-all/src/routes/sign-solana.ts +++ b/backend-all/src/routes/sign-solana.ts @@ -8,8 +8,15 @@ import { GetTransactionSignationDto } from '@/types' export default (): Resource => ({ async get(req: Request<{}, {}, {}, GetTransactionSignationDto>, res) { try { - - const { fromBridgeAddress, toBridgeAssistAddress, fromChain, fromUser, index, _tokenMint } = req.query + const { + fromBridgeAddress, + toBridgeAssistAddress, + fromChain, + fromUser, + index, + transactionId, + tokenMint, + } = req.query if (!fromBridgeAddress) return res.status(400).send('fromBridgeAddress not specified') @@ -18,17 +25,19 @@ export default (): Resource => ({ if (!fromChain) return res.status(400).send('from chain not specified') if (!fromUser) return res.status(400).send('from user not specified') if (!index) return res.status(400).send('index not specified') - if (!_tokenMint) return res.status(400).send('token mint not specified') + if (!transactionId) return res.status(400).send('transactionId not specified') + if (!tokenMint) return res.status(400).send('tokenMint not specified') const signature = await signEvmToSolana( fromChain, fromBridgeAddress, toBridgeAssistAddress, fromUser, index, - _tokenMint + tokenMint, + transactionId ) - res.status(200).json({signature}) + res.status(200).json({ signature }) } catch (error: any) { console.log(error, 'error') res.status(400).json({ error: error.message }) diff --git a/backend-all/src/routes/sign.ts b/backend-all/src/routes/sign.ts index b3244fe..727fa33 100644 --- a/backend-all/src/routes/sign.ts +++ b/backend-all/src/routes/sign.ts @@ -8,7 +8,7 @@ import { GetTransactionSignationDto } from '@/types' export default (): Resource => ({ async get(req: Request<{}, {}, {}, GetTransactionSignationDto>, res) { try { - const { fromBridgeAddress, toBridgeAssistAddress, fromChain, fromUser, index } = + const { fromBridgeAddress, toBridgeAssistAddress, fromChain, fromUser, index, transactionId } = req.query if (!fromBridgeAddress) @@ -18,12 +18,14 @@ export default (): Resource => ({ if (!fromChain) return res.status(400).send('from chain not specified') if (!fromUser) return res.status(400).send('from user not specified') if (!index) return res.status(400).send('index not specified') + if (!transactionId) return res.status(400).send('transactionId not specified') const signature = await signTransaction( fromBridgeAddress, toBridgeAssistAddress, fromChain, - fromUser, + fromUser, index, + transactionId, req ) diff --git a/backend-all/src/routes/tokens/balance-by-blocktag.ts b/backend-all/src/routes/tokens/balance-by-blocktag.ts new file mode 100644 index 0000000..5f6e75a --- /dev/null +++ b/backend-all/src/routes/tokens/balance-by-blocktag.ts @@ -0,0 +1,39 @@ +import { type Request } from 'express' +import type { Resource } from 'express-automatic-routes' +import { tokenService } from '@/services' +import { ChainId } from '@/gotbit-tools/node/types'; +// import axios from 'axios' + +export default (): Resource => ({ + async get( + req: Request< + {}, + {}, + {}, + { userAddress?: string; blockTag?: number; tokenAddress?: string; chainId?: string } + >, + res + ) { + try { + const { userAddress, blockTag, tokenAddress, chainId } = req.query + if (!userAddress) + return res.status(400).json({ error: 'userAddress not specified' }) + if (!blockTag) return res.status(400).json({ error: 'blockTag not specified' }) + if (!tokenAddress) + return res.status(400).json({ error: 'tokenAddress not specified' }) + if (!chainId) return res.status(400).json({ error: 'chainId not specified' }) + const response = await tokenService.getTokenBalanceByBlockTag( + userAddress as string, + blockTag as number, + tokenAddress as string, + chainId as ChainId + ) + res.status(200).json({ + success: true, + data: response, + }) + } catch (error: any) { + res.status(400).json({ error: error.message }) + } + }, +}) diff --git a/backend-all/src/routes/tokens/index.ts b/backend-all/src/routes/tokens/index.ts new file mode 100644 index 0000000..891bbc5 --- /dev/null +++ b/backend-all/src/routes/tokens/index.ts @@ -0,0 +1,19 @@ +import { type Request } from 'express' +import type { Resource } from 'express-automatic-routes' +import { tokenService } from '@/services' +// import axios from 'axios' + +export default (): Resource => ({ + async get(req: Request<{}, {}, {}, {}>, res) { + try { + + const response = await tokenService.getTokens() + res.status(200).json({ + success: true, + data: response, + }) + } catch (error: any) { + res.status(400).json({ error: error.message }) + } + }, +}) diff --git a/backend-all/src/routes/transactions/index.ts b/backend-all/src/routes/transactions/index.ts new file mode 100644 index 0000000..604e672 --- /dev/null +++ b/backend-all/src/routes/transactions/index.ts @@ -0,0 +1,99 @@ +import { query, type Request } from 'express' +import type { Resource } from 'express-automatic-routes' +import { bridgeService } from '@/services' +import { + GetUserTransactionDto, + AddTransactionDto, + MarkTransactionAsClaimedDto, +} from '@/types' +// import axios from 'axios' + +export default (): Resource => ({ + async get(req: Request<{}, {}, {}, any>, res) { + try { + let { chainIds, fulfilled, limit, page, userAddress, symbol, forceSync, secondaryAddress } = req.query + if (!userAddress) { + return res.status(400).json({ error: 'User address not specified' }) + } + let _page = 1 + let _limit = 10 + if (page) { + _page = +page + } + if (limit) { + _limit = +limit + } + const options = { page: _page, limit: _limit } + const response = await bridgeService.getUserTransactions( + userAddress, + options, + secondaryAddress, + chainIds, + fulfilled, + forceSync, + symbol, + ) + res.status(200).json({ + success: true, + data: response, + }) + } catch (error: any) { + res.status(400).json({ error: error.message }) + } + }, + + async post(req: Request<{}, {}, AddTransactionDto>, res) { + try { + const { bridgeId, index, userAddress, transactionHash } = req.body + + // Validate required fields + if (!bridgeId || !index || !userAddress) { + return res.status(400).json({ + error: 'Missing required fields: bridgeId, index, userAddress', + }) + } + + const dto: AddTransactionDto = { + bridgeId, + index, + userAddress, + transactionHash, + } + + const response = await bridgeService.addTransaction(dto) + + res.status(201).json({ + success: true, + data: response, + }) + } catch (error: any) { + res.status(400).json({ error: error.message }) + } + }, + + async put(req: Request<{}, {}, MarkTransactionAsClaimedDto>, res) { + try { + const { transactionId, claimTransactionHash, toBridgeId } = req.body + if (!transactionId || !claimTransactionHash || !toBridgeId) { + return res + .status(400) + .json({ + error: + 'Missing required fields: transactionId, claimTransactionHash, toBridgeId', + }) + } + const dto: MarkTransactionAsClaimedDto = { + transactionId, + claimTransactionHash, + toBridgeId, + } + const response = await bridgeService.markTransactionAsClaimed(dto) + res.status(200).json({ + success: true, + data: response, + }) + } catch (error: any) { + res.status(400).json({ error: error.message }) + } + }, +}) diff --git a/backend-all/src/services/blockchain.ts b/backend-all/src/services/blockchain.ts index 86d99e9..0ccc470 100644 --- a/backend-all/src/services/blockchain.ts +++ b/backend-all/src/services/blockchain.ts @@ -1,4 +1,3 @@ - import { Wallet, ethers, BigNumber, BigNumberish, providers, utils } from 'ethers' import { useContracts, getProvider, safeRead } from '@/gotbit-tools/node' import { config } from '@/gotbit.config' @@ -29,6 +28,7 @@ import { _getProvider, hasPassedConfirmationEvm } from '@/utils/helpers' import { anyBridgeAssist, anyToken } from '@/utils/useContracts' import { relayerIndex } from '@/utils/env-var' import { BridgeAssist, Token } from '@/contracts/typechain' +import { transactionRepo } from '@/lib/database' export const getWalletEVM = () => new Wallet(process.env.PRIVATE_KEY!) @@ -76,12 +76,17 @@ export const signTransaction = async ( fromChain: string, fromUser: string, index: string, + transactionId: string, req: any ) => { let tx: TransactionContract let relayers = 1 - if (!fromChain.startsWith('evm.')) throw Error(`Relayer ${relayerIndex} Bad arguments`) - const _fromChain = fromChain.slice(4) as ChainId + // if (!fromChain.startsWith('evm.')) throw Error(`Relayer ${relayerIndex} Bad arguments`) + if (process.env.IS_PUBLIC_RELAYER === 'true') { + const dbTransaction = await transactionRepo.findOne({ id: transactionId }) + if (!dbTransaction) throw Error('Transaction not found') + } + const _fromChain = fromChain.replace('evm.', '') as ChainId const _provider = await _getProvider(_fromChain) const contract = anyBridgeAssist(fromBridgeAddress, _provider) const transactionPromise = contract.transactions(fromUser, index) @@ -102,10 +107,15 @@ export const signTransaction = async ( if (currentBlock === 0 || tx.block.gt(currentBlock)) throw Error(`Relayer ${relayerIndex} waiting for confirmations`) - - if (!tx.toChain.startsWith('evm.')) throw Error(`Relayer ${relayerIndex} bad contract params`) - const {isFulfilled} = await fulfilledInfo(tx, toBridgeAddress) - if (isFulfilled) throw new Error('Token has already claimed') + if (!tx.toChain.startsWith('evm.')) + throw Error(`Relayer ${relayerIndex} bad contract params`) + const { isFulfilled } = await fulfilledInfo(tx, toBridgeAddress) + if (isFulfilled) { + if (process.env.IS_PUBLIC_RELAYER === 'true') { + await transactionRepo.update(transactionId, { fulfilled: true }) + } + throw new Error('Token has already claimed') + } // if (tx.toChain.startsWith('evm.')) { const chainId = tx.toChain.replace('evm.', '') @@ -129,7 +139,10 @@ export const signTransaction = async ( const relayer1Url = process.env.RELAYER1_URL const relayer2Url = process.env.RELAYER2_URL - const promises = [getSignaturesFromRelayer(relayer1Url, req.query), getSignaturesFromRelayer(relayer2Url, req.query)] + const promises = [ + getSignaturesFromRelayer(relayer1Url, req.query), + getSignaturesFromRelayer(relayer2Url, req.query), + ] const results = await Promise.all(promises) signatures = signatures.concat(results[0], results[1]) } @@ -174,13 +187,16 @@ export async function signEvmToSolana( toBridgeAddress: string, fromUser: string, index: string, - _tokenMint: string + _tokenMint: string, + transactionId: string ) { - const { tokenMint, connection, owner } = solanaWorkspace(toBridgeAddress, _tokenMint) - + const { connection, owner, tokenMint } = solanaWorkspace(toBridgeAddress, _tokenMint) // console.log(connection, 'connection') - - const fromChain = fromChainId.slice(4) as ChainId + if (process.env.IS_PUBLIC_RELAYER === 'true') { + const dbTransaction = await transactionRepo.findOne({ id: transactionId }) + if (!dbTransaction) throw Error('Transaction not found') + } + const fromChain = fromChainId.replace('evm.', '') as ChainId const _provider = await _getProvider(fromChain) const contract = anyBridgeAssist(fromBridgeAddress, _provider) const tx = await contract.transactions(fromUser, index) @@ -191,12 +207,14 @@ export async function signEvmToSolana( new PublicKey(userSolana), owner ) - console.log(userTokenAccountKey.toBase58(), 'kdkdsk') const extractedTx = extractTransaction(tx) - if (await isToSolanaTxFulfilled(toBridgeAddress, _tokenMint, fromChain, tx.nonce)) + if (await isToSolanaTxFulfilled(toBridgeAddress, _tokenMint, fromChain, tx.nonce)) { + if (process.env.IS_PUBLIC_RELAYER === 'true') { + await transactionRepo.update(transactionId, { fulfilled: true }) + } throw Error('Already claimed') - + } const blockConfirmed = hasPassedConfirmationEvm(_provider, fromChain, tx.block) @@ -219,10 +237,17 @@ export async function signSolanaToEvm( toBridgeAddress: string, userSolana: string, nonce: string, - _tokenMint: string + _tokenMint: string, + transactionId: string ) { - const { owner, tokenMint, program, connection } = solanaWorkspace(fromBridgeAddress, _tokenMint) - + const { owner, program, connection, tokenMint } = solanaWorkspace( + fromBridgeAddress, + _tokenMint + ) + if (process.env.IS_PUBLIC_RELAYER === 'true') { + const dbTransaction = await transactionRepo.findOne({ id: transactionId }) + if (!dbTransaction) throw Error('Transaction not found') + } const tx = await getSolanaSendTx( owner, tokenMint, @@ -231,7 +256,7 @@ export async function signSolanaToEvm( nonce, fromChain ) - const _provider = await _getProvider(tx.toChain.slice(4) as ChainId) + const _provider = await _getProvider(tx.toChain.replace('evm.', '') as ChainId) const contract = anyBridgeAssist(toBridgeAddress, _provider) const fulfilledAt = await safeRead( @@ -240,7 +265,12 @@ export async function signSolanaToEvm( ) const isClaimed = fulfilledAt.toNumber() !== 0 - if (isClaimed) throw Error('Already claimed') + if (isClaimed) { + if (process.env.IS_PUBLIC_RELAYER === 'true') { + await transactionRepo.update(transactionId, { fulfilled: true }) + } + throw Error('Already claimed') + } if (!(await hasPassedConfirmationSolana(connection, tx))) throw Error('Not confirmed yet') @@ -248,7 +278,6 @@ export async function signSolanaToEvm( const relayerLength = await contract.relayersLength() const relayers = relayerLength.toNumber() const chainId = tx.toChain.replace('evm.', '') - // const { bridgeAssist } = useContracts(undefined, chainId as ChainId) let signatures: string[] = [] const allowedIps = process.env.ALLOWED_IPS?.split(',') const clientIp = getClientIp(req) @@ -258,35 +287,29 @@ export async function signSolanaToEvm( } } const fulfilTX = extractFulfillTransaction(tx) - console.log(fulfilTX, 'ksksks') const signer0 = await signHashedTransaction(fulfilTX, chainId, toBridgeAddress, 0) signatures.push(signer0) if (process.env.IS_PUBLIC_RELAYER === 'true' && relayers > 1) { const relayersLength = relayers - 1 const relayer1Url = process.env.RELAYER1_URL const relayer2Url = process.env.RELAYER2_URL - for (let i = 1; i <= relayersLength; i++) { - try { - if (i === 1) { - const res = await axios.get(geturl(relayer1Url, req.query)) - signatures = signatures.concat(res.data.signature) - } - if (i === 2) { - const res = await axios.get(geturl(relayer2Url, req.query)) - signatures = signatures.concat(res.data.signature) - } - } catch (error: any) { - console.log(error, 'dkdkdkdk') - throw new Error(`relayer ${i + 1} error: ${error.message}`) - } - } + const promises = [ + getSignaturesFromRelayer(relayer1Url, req.query), + getSignaturesFromRelayer(relayer2Url, req.query), + ] + const results = await Promise.all(promises) + signatures = signatures.concat(results[0], results[1]) } return signatures } -async function checkToken(user: string, bridgeAssist: BridgeAssist, fromChain: ChainId, transaction: TransactionContract) { +async function checkToken( + user: string, + bridgeAssist: BridgeAssist, + fromChain: ChainId, + transaction: TransactionContract +) { const timeStamp = Number(transaction.timestamp.toString()) - console.log(timeStamp, 'tx timesamp') if (timeStamp < targetTimeStamp(fromChain)) { console.log('Transaction before target timestamp') console.log('no need to check') @@ -353,7 +376,6 @@ async function fulfilledInfo(tx: TransactionContract, bridgeAddress: string) { } } - export type ARB_CHAINID = '42161' | '421614' export const targetBlockNumber = (chainId: ChainId) => chainId === '42161' ? 370576662 : 180981641 diff --git a/backend-all/src/services/bridge.ts b/backend-all/src/services/bridge.ts new file mode 100644 index 0000000..bd6655e --- /dev/null +++ b/backend-all/src/services/bridge.ts @@ -0,0 +1,809 @@ +import { ChainId } from '@/gotbit-tools/node/types' +import { + blockscanInfoRepo, + BridgeInfo, + bridgeInfoRepo, + tokenRepo, + transactionRepo, + userTransactionSyncRepo, +} from '@/lib/database' +import { Token } from '@/lib/database/entities/Token' +import { _oldRWABridge, BRIDGEASSISTS } from '@/utils/constant' +import { _getProvider, isEvmAddress, isSolChain, useOldRwaBridge } from '@/utils/helpers' +import { anyBridgeAssist } from '@/utils/useContracts' +import { BigNumber, providers } from 'ethers' +import CONFIRMATIONS from '../confirmations.json' +import { Transaction } from '@/lib/database/entities/Transaction' +import EventLogger from '@/lib/logger/index.logger' +import { clusterApiUrl, Connection, PublicKey } from '@solana/web3.js' +import { + CHAIN_TO_BUFFER, + getSolanaSendTx, + SOL_CHAIN_BUFFER, + SOLANA_PROGRAM_VERSION, + solanaWorkspace, +} from '@/utils/solana/helpers' +import { BN, Program } from '@coral-xyz/anchor' +import { AssetchainBridgeSolana } from '@/utils/solana/types/assetchain_bridge_solana' +import { + AddTransactionDto, + ChainType, + ITransaction, + MarkTransactionAsClaimedDto, + TransactionContract, +} from '@/types' +import { isProd } from '@/utils/env-var' +// import { AddTransactionDto } from '@/types' + +export class BridgeService { + async addBridge( + bridgeAddress: string, + chainId: string, + token: Token, + provider: providers.JsonRpcProvider + ) { + const existingBridge = await bridgeInfoRepo.findOne({ bridgeAddress, chainId }) + if (existingBridge) { + return existingBridge + } + + const bridge = anyBridgeAssist(bridgeAddress, provider) + const feeFulfillPromise = bridge.feeFulfill() + const feeSendPromise = bridge.feeSend() + const limitPerSendPromise = bridge.limitPerSend() + const tokenDecimalPromise = token.decimal + + const [feeFulfill, feeSend, limitPerSend, tokenDecimal] = await Promise.all([ + feeFulfillPromise, + feeSendPromise, + limitPerSendPromise, + tokenDecimalPromise, + ]) + + const fees = { + feeFulfill: +feeFulfill.toString(), + feeSend: +feeSend.toString(), + } + const _limitPerSend = limitPerSend.toString().includes('e+') + ? BigInt(Math.round(Number(limitPerSend.toString()))).toString() + : limitPerSend.toString() + + const bridgeInfo = bridgeInfoRepo.create({ + bridgeAddress, + chainId, + token, + fees, + limitPerSend: _limitPerSend, + tokenDecimal, + }) + await bridgeInfoRepo.save(bridgeInfo) + return bridgeInfo + } + + async addSolanaBridge(bridgeAddress: string, chainId: string, token: Token) { + try { + const existingBridge = await bridgeInfoRepo.findOne({ + bridgeAddress, + chainId, + token: { id: token.id }, + }) + if (existingBridge) { + return existingBridge + } + + const { owner, program } = solanaWorkspace(bridgeAddress, token.tokenAddress) + const tokenMint = new PublicKey(token.tokenAddress) + + const [bridgeParamsPda] = PublicKey.findProgramAddressSync( + [ + SOLANA_PROGRAM_VERSION().toBuffer('be', 8), + Buffer.from('bridge_params'), + owner.publicKey.toBuffer(), + tokenMint.toBuffer(), + SOL_CHAIN_BUFFER(), + ], + program.programId + ) + + const bridgeParams = await program.account.bridgeParams.fetch(bridgeParamsPda) + + if (!bridgeParams) { + EventLogger.warn(`no params`) + return + } + + const fees = { + feeFulfill: +bridgeParams.feeFulfill.toString(), + feeSend: +bridgeParams.feeSend.toString(), + } + const _limitPerSend = bridgeParams.limitSend.toString().includes('e+') + ? BigInt(Math.round(Number(bridgeParams.limitSend.toString()))).toString() + : bridgeParams.limitSend.toString() + + const bridgeInfo = bridgeInfoRepo.create({ + bridgeAddress, + chainId, + token, + fees, + limitPerSend: _limitPerSend, + tokenDecimal: token.decimal, + }) + await bridgeInfoRepo.save(bridgeInfo) + return bridgeInfo + } catch (error) { + console.log(error, 'solana') + } + } + + async getTransactionFromOnChain( + userAddress: string, + options: any, + _chainIds?: string[], + _fulfilled?: boolean, + symbol?: string + ) { + try { + const chainIds = Object.keys(BRIDGEASSISTS) + const _bridgeAssists = await bridgeInfoRepo.find({}) + const providers: any = {} + await Promise.all( + chainIds.map(async (chainId) => { + if (isSolChain(chainId)) { + return + } + const provider = await _getProvider(chainId as any) + providers[chainId as ChainId] = provider + }) + ) + + const dbtransactions: Transaction[] = [] + await Promise.all( + _bridgeAssists.map(async (bridgeAssist) => { + const chainId = bridgeAssist.chainId + if (isSolChain(chainId)) { + return + } + const provider = providers[chainId as ChainId] + const contract = anyBridgeAssist(bridgeAssist.bridgeAddress, provider) + const transactions = await contract.getUserTransactions(userAddress) + await Promise.all( + transactions.map(async (transaction, index) => { + // console.log(transaction.nonce.toString(), 'dkdkdkdkd') + // console.log(+transaction.nonce.toString(), '043489') + let existingTransaction = await transactionRepo.findOne({ + userAddress, + index: index, + bridgeInfo: { + id: bridgeAssist.id, + }, + }) + if (existingTransaction) { + if (existingTransaction.fulfilled) { + return + } + if (isSolChain(existingTransaction.toChain)) { + const isFulfilled = await this.processSolanaIsFulfilled( + _bridgeAssists, + chainId as ChainId, + transaction, + bridgeAssist + ) + existingTransaction.fulfilled = isFulfilled + await transactionRepo.save(existingTransaction) + return + } else { + const isFulfilled = await this.processEvmIsFulfilled( + _bridgeAssists, + providers, + transaction, + bridgeAssist + ) + existingTransaction.fulfilled = isFulfilled + await transactionRepo.save(existingTransaction) + return + } + } + const toChainId = transaction.toChain.replace('evm.', '') as ChainId + let isFulfilled = false + if (isSolChain(toChainId)) { + isFulfilled = await this.processSolanaIsFulfilled( + _bridgeAssists, + chainId as ChainId, + transaction, + bridgeAssist + ) + } else { + isFulfilled = await this.processEvmIsFulfilled( + _bridgeAssists, + providers, + transaction, + bridgeAssist + ) + } + + const txBlock = transaction.block.toString() + const confirmations = CONFIRMATIONS[chainId as ChainId] + + const transactionDate = new Date(Number(transaction.timestamp) * 1000) + const transactionObject = transactionRepo.create({ + amount: transaction.amount.toString(), + timestamp: transaction.timestamp.toString(), + fromUser: transaction.fromUser, + toUser: transaction.toUser, + fromChain: transaction.fromChain.replace('evm.', ''), + toChain: transaction.toChain.replace('evm.', ''), + nonce: +transaction.nonce.toString(), + fulfillAmount: transaction.amount.toString(), + fulfilled: isFulfilled, + fulfillToUser: transaction.toUser, + fulfillFromChain: transaction.fromChain.replace('evm.', ''), + fulfillNonce: +transaction.nonce.toString(), + txBlock, + confirmations, + transactionDate, + bridgeInfo: bridgeAssist, + chainId, + fulfillFromUser: transaction.fromUser, + index: index, + userAddress: userAddress, + symbol: bridgeAssist.token.symbol, + }) + + EventLogger.info( + `Created transaction: ${transactionObject.index} on ${chainId}` + ) + dbtransactions.push(transactionObject) + }) + ) + }) + ) + await transactionRepo.save(dbtransactions as any) + let syncTransaction = await userTransactionSyncRepo.findOne({ + userAddress, + synced: true, + chainType: ChainType.EVM, + }) + if (!syncTransaction) { + syncTransaction = userTransactionSyncRepo.create({ + userAddress, + synced: true, + chainType: ChainType.EVM, + }) + await userTransactionSyncRepo.save(syncTransaction) + } + + EventLogger.info(`Inserted ${dbtransactions.length} transactions`) + return await transactionRepo.findTransactionsByUserWithPagination( + userAddress, + options, + _chainIds, + _fulfilled, + symbol + ) + } catch (error: any) { + console.log(error) + EventLogger.error(`Error inserting transactions: ${error.message}`) + throw error + } + } + + async getSolanaTransactionFromOnChain( + userAddress: string, + options: any, + _chainIds: string[], + _fulfilled?: boolean, + _symbol?: string + ) { + try { + const chainId = isProd ? 'sol.mainnet' : 'sol.devnet' + const chainIds = Object.keys(BRIDGEASSISTS) + const bridgeAssists = await bridgeInfoRepo.find({}) + const solanaBridgeAssists = bridgeAssists.filter((b) => b.chainId === chainId) + const notSolanaBridgeAssists = bridgeAssists.filter((b) => b.chainId !== chainId) + const providers: any = {} + const dbtransactions: Transaction[] = [] + await Promise.all( + chainIds.map(async (chainId) => { + if (isSolChain(chainId)) { + return + } + const provider = await _getProvider(chainId as any) + providers[chainId as ChainId] = provider + }) + ) + + for (let bridgeAssist of solanaBridgeAssists) { + EventLogger.info(`Processing transactions for ${bridgeAssist.bridgeAddress}`) + const { owner, program } = solanaWorkspace(bridgeAssist.bridgeAddress, bridgeAssist.token.tokenAddress) + const tokenMint = new PublicKey(bridgeAssist.token.tokenAddress) + + const [sendNoncePda] = PublicKey.findProgramAddressSync( + [ + SOLANA_PROGRAM_VERSION().toBuffer('be', 8), + Buffer.from('send_nonce'), + owner.publicKey.toBuffer(), + tokenMint.toBuffer(), + new PublicKey(userAddress).toBuffer(), + SOL_CHAIN_BUFFER(), + ], + program.programId + ) + // console.log(sendNoncePda, 'sendNoncePda') + + let nonceAccount + try { + nonceAccount = await program.account.userNonce.fetch(sendNoncePda) + EventLogger.info(`nonceAccount: ${nonceAccount.nonce.toString()}`) + } catch (e: any) { + // If it doesn't exist yet, default to 0 + if (e.message.includes('Account does not exist')) { + nonceAccount = { nonce: new BN(0) } + } else { + throw e + } + } + const currentNonce = new BN(nonceAccount.nonce) + EventLogger.info(`currentNonce: ${currentNonce.toString()}`) + + // Convert BN to number for array creation + const nonceCount = Number(currentNonce.toString()) + + const transactionPromises = Array.from({ length: nonceCount }, (_, index) => { + const i = new BN(index) + return getSolanaSendTx( + owner, + tokenMint, + program, + new PublicKey(userAddress), + i.toString(), + bridgeAssist.chainId + ) + }) + const transactions = await Promise.all(transactionPromises) + for (let index = 0; index < transactions.length; index++) { + const transaction = transactions[index] + const existingTransaction = await transactionRepo.findOne({ + userAddress, + index: index, + bridgeInfo: { + id: bridgeAssist.id, + }, + }) + if (existingTransaction) { + const isFulfilled = await this.processEvmIsFulfilled( + notSolanaBridgeAssists, + providers, + transaction, + bridgeAssist + ) + existingTransaction.fulfilled = isFulfilled + await transactionRepo.save(existingTransaction) + continue + } + const isFulfilled = await this.processEvmIsFulfilled( + notSolanaBridgeAssists, + providers, + transaction, + bridgeAssist + ) + const dbTransaction = transactionRepo.create({ + userAddress, + index: index, + chainId: bridgeAssist.chainId, + bridgeInfo: bridgeAssist, + amount: transaction.amount.toString(), + timestamp: transaction.timestamp.toString(), + fromUser: userAddress, + toUser: transaction.toUser, + fromChain: transaction.fromChain, + toChain: transaction.toChain, + nonce: +transaction.nonce.toString(), + fulfillAmount: transaction.amount.toString(), + fulfilled: isFulfilled, + fulfillToUser: transaction.toUser, + fulfillFromChain: chainId, + fulfillNonce: +transaction.nonce.toString(), + txBlock: transaction.block.toString(), + confirmations: CONFIRMATIONS[bridgeAssist.chainId as ChainId], + transactionDate: new Date(Number(transaction.timestamp) * 1000), + symbol: bridgeAssist.token.symbol, + fulfillFromUser: userAddress, + }) + EventLogger.info( + `Created transaction: ${dbTransaction.index} on ${bridgeAssist.chainId}` + ) + dbtransactions.push(dbTransaction) + } + await transactionRepo.save(dbtransactions as any) + let syncTransaction = await userTransactionSyncRepo.findOne({ + userAddress, + synced: true, + chainType: ChainType.SOLANA, + }) + if (!syncTransaction) { + syncTransaction = userTransactionSyncRepo.create({ + userAddress, + synced: true, + chainType: ChainType.SOLANA, + }) + await userTransactionSyncRepo.save(syncTransaction) + } + EventLogger.info(`Inserted ${dbtransactions.length} transactions`) + } + return await transactionRepo.findTransactionsByUserWithPagination( + userAddress, + options, + _chainIds, + _fulfilled, + _symbol + ) + } catch (error: any) { + console.log(error) + EventLogger.error(`Error inserting transactions: ${error.message}`) + throw error + } + } + + async getUserTransactions( + userAddress: string, + options: any, + secondaryAddress?: string, + _chainIds?: string, + _fulfilled?: string, + forceSync?: string, + symbol?: string + ) { + const _isEvmAddress = isEvmAddress(userAddress) + const dbChainIds = _chainIds ? _chainIds.split(',') : [] + const dbFulfilled = _fulfilled ? (_fulfilled === 'true' ? true : false) : undefined + const dbForceSync = forceSync ? (forceSync === 'true' ? true : false) : undefined + EventLogger.info(`_chainIds: ${_chainIds}, _fulfilled: ${_fulfilled}, forceSync: ${forceSync}, symbol: ${symbol}`) + + EventLogger.info(`dbChainIds: ${dbChainIds}, dbFulfilled: ${dbFulfilled}, dbForceSync: ${dbForceSync}`) + const syncTransaction = await userTransactionSyncRepo.findOne({ + userAddress, + synced: true, + chainType: _isEvmAddress ? ChainType.EVM : ChainType.SOLANA, + }) + if (dbForceSync || !syncTransaction) { + if (_isEvmAddress) { + return await this.getTransactionFromOnChain( + userAddress, + options, + dbChainIds, + dbFulfilled, + symbol + ) + } else { + return await this.getSolanaTransactionFromOnChain( + userAddress, + options, + dbChainIds, + dbFulfilled, + symbol + ) + } + } + return await transactionRepo.findTransactionsByUserWithPagination( + userAddress, + options, + dbChainIds, + dbFulfilled, + symbol, + secondaryAddress + ) + } + + async addTransaction(dto: AddTransactionDto) { + try { + const { + index, + + userAddress, + transactionHash, + bridgeId, + } = dto + const bridgeInfo = await bridgeInfoRepo.findById(bridgeId) + if (!bridgeInfo) throw new Error(`Bridge not found`) + const chainId = bridgeInfo.chainId + if (isSolChain(chainId)) { + const { owner, tokenMint, program, connection } = solanaWorkspace( + bridgeInfo.bridgeAddress, + bridgeInfo.token.tokenAddress + ) + const tx = await getSolanaSendTx( + owner, + tokenMint, + program, + new PublicKey(userAddress), + index, + chainId + ) + if (tx.block.lte(0)) { + throw new Error(`Transaction not found`) + } + const dbTransaction = await transactionRepo.findOne({ + userAddress, + index: +index, + bridgeInfo: { id: bridgeId }, + }) + if (dbTransaction) { + return { + data: dbTransaction, + message: 'Transaction already exists', + success: true, + } + } + // const bridgeInfo = await bridgeInfoRepo.findOne({ + // bridgeAddress, + // chainId, + // }) + const newTransaction = transactionRepo.create({ + userAddress, + index: +index, + chainId, + bridgeInfo, + amount: tx.amount.toString(), + timestamp: tx.timestamp.toString(), + fromUser: tx.fromUser, + toUser: tx.toUser, + fromChain: tx.fromChain, + toChain: tx.toChain.replace('evm.', ''), + nonce: +tx.nonce.toString(), + fulfillAmount: tx.amount.toString(), + fulfilled: false, + fulfillToUser: tx.toUser, + fulfillFromChain: tx.fromChain.replace('evm.', ''), + fulfillNonce: +tx.nonce.toString(), + txBlock: tx.block.toString(), + confirmations: CONFIRMATIONS[chainId as ChainId], + transactionDate: new Date(Number(tx.timestamp) * 1000), + symbol: bridgeInfo.token.symbol, + bridgeInfoId: bridgeInfo.id, + fulfillFromUser: tx.fromUser, + transactionHash, + }) + await transactionRepo.save(newTransaction as any) + + return { + data: newTransaction, + message: 'Transaction added successfully', + success: true, + } + } + const provider = await _getProvider(chainId as ChainId) + const contract = anyBridgeAssist(bridgeInfo.bridgeAddress, provider) + const transaction = await contract.transactions(userAddress, index) + if (transaction.block.lte(0)) { + throw new Error(`Transaction not found`) + } + const dbTransaction = await transactionRepo.findOne({ + userAddress, + index: +index, + bridgeInfo: { + id: bridgeId, + }, + }) + if (dbTransaction) { + return { + data: dbTransaction, + message: 'Transaction already exists', + success: true, + } + } + const newTransaction = transactionRepo.create({ + userAddress, + index: +index, + chainId, + bridgeInfo, + amount: transaction.amount.toString(), + timestamp: transaction.timestamp.toString(), + fromUser: transaction.fromUser, + toUser: transaction.toUser, + fromChain: transaction.fromChain.replace('evm.', ''), + toChain: transaction.toChain.replace('evm.', ''), + nonce: +transaction.nonce.toString(), + fulfillAmount: transaction.amount.toString(), + fulfilled: false, + fulfillToUser: transaction.toUser, + fulfillFromChain: transaction.fromChain.replace('evm.', ''), + fulfillNonce: +transaction.nonce.toString(), + txBlock: transaction.block.toString(), + confirmations: CONFIRMATIONS[chainId as ChainId], + transactionDate: new Date(Number(transaction.timestamp) * 1000), + symbol: bridgeInfo.token.symbol, + bridgeInfoId: bridgeInfo.id, + fulfillFromUser: transaction.fromUser, + transactionHash, + }) + await transactionRepo.save(newTransaction as any) + + return { + data: newTransaction, + message: 'Transaction added successfully', + success: true, + } + } catch (error) { + throw error + } + } + + async markTransactionAsClaimed(dto: MarkTransactionAsClaimedDto) { + try { + const { transactionId, claimTransactionHash, toBridgeId } = dto + const dbTransaction = await transactionRepo.findById(transactionId) + if (!dbTransaction) throw new Error(`Transaction not found`) + if (dbTransaction.fulfilled) { + return { + data: dbTransaction, + message: 'Transaction already fulfilled', + success: true, + } + } + const chainId = dbTransaction.toChain.replace('evm.', '') + const toBridgeInfo = await bridgeInfoRepo.findById(toBridgeId) + if (!toBridgeInfo) throw new Error(`Bridge not found`) + if (isSolChain(chainId)) { + const { owner, tokenMint, program, connection } = solanaWorkspace( + toBridgeInfo.bridgeAddress, toBridgeInfo.token.tokenAddress + ) + const isFulfilled = await this.isToSolanaTxFulfilled( + toBridgeInfo.bridgeAddress, + toBridgeInfo.token.tokenAddress, + dbTransaction.fromChain.replace('evm.', '') as ChainId, + BigNumber.from(dbTransaction.nonce), + owner.publicKey, + program + ) + if (isFulfilled) { + dbTransaction.fulfilled = true + dbTransaction.claimTransactionHash = claimTransactionHash + await transactionRepo.save(dbTransaction) + } + return { + data: dbTransaction, + message: 'Transaction marked as claimed', + success: true, + } + } + const provider = await _getProvider(chainId as ChainId) + const contract = anyBridgeAssist(toBridgeInfo.bridgeAddress, provider) + let fromChain = dbTransaction.fromChain.replace(`evm.`, '') + if (!isSolChain(fromChain)){ + fromChain = `evm.${fromChain}` + } + const fulfilledAt = await contract.fulfilledAt( + fromChain, + dbTransaction.fromUser, + dbTransaction.nonce + ) + const isFulfilled = !fulfilledAt.eq(0) + if (isFulfilled) { + dbTransaction.fulfilled = true + dbTransaction.claimTransactionHash = claimTransactionHash + await transactionRepo.save(dbTransaction) + } + + return { + data: dbTransaction, + message: 'Transaction marked as claimed', + success: true, + } + } catch (error) { + throw error + } + } + + async isToSolanaTxFulfilled( + toBridgeAddress: string, + token: string, + fromChainId: ChainId, + _nonce: BigNumber, + owner: PublicKey, + program: Program + ): Promise { + const nonce = new BN(_nonce.toString()) + + const tokenMint = new PublicKey(token) + const programId = new PublicKey(toBridgeAddress) + + const CURRENT_CHAIN = 'evm.' + fromChainId + + const [emptyAccount] = PublicKey.findProgramAddressSync( + [ + SOLANA_PROGRAM_VERSION().toBuffer('be', 8), + Buffer.from('fulfilled'), + owner.toBuffer(), + tokenMint.toBuffer(), + nonce.toBuffer('be', 8), + CHAIN_TO_BUFFER(CURRENT_CHAIN), + SOL_CHAIN_BUFFER(), + ], + programId + ) + + // console.log(emptyAccount.toBase58(), 'emptyAccount') + + const emptyAccountInfo = await program.provider.connection.getAccountInfo( + emptyAccount + ) + + return emptyAccountInfo !== null + } + + async processSolanaIsFulfilled( + _bridgeAssists: BridgeInfo[], + chainId: ChainId, + transaction: TransactionContract, + bridge: BridgeInfo + ) { + const toChainId = transaction.toChain.replace('evm.', '') as ChainId + let symbol = bridge.token.symbol + const toBridgeAssist = _bridgeAssists.find( + (b) => b.chainId === toChainId && b.token.symbol === symbol + ) + if (!toBridgeAssist) { + EventLogger.info(`To Bridge not found`) + return false + } + const { owner, program } = solanaWorkspace(toBridgeAssist.bridgeAddress, toBridgeAssist.token.tokenAddress) + + const isFulfilled = await this.isToSolanaTxFulfilled( + toBridgeAssist.bridgeAddress, + toBridgeAssist.token.tokenAddress, + chainId as ChainId, + transaction.nonce, + owner.publicKey, + program + ) + if (isFulfilled) { + EventLogger.info( + `Transaction ${transaction.nonce.toString()} already fulfilled on ${toChainId}` + ) + return true + } + EventLogger.info( + `Transaction ${transaction.nonce.toString()} not fulfilled on ${toChainId}` + ) + return false + } + + async processEvmIsFulfilled( + _bridgeAssists: BridgeInfo[], + providers: any, + transaction: TransactionContract | ITransaction, + bridge: BridgeInfo + ) { + const toChainId = transaction.toChain.replace('evm.', '') as ChainId + + const toBridgeAssist = _bridgeAssists.find( + (b) => b.chainId === toChainId && b.token.symbol === bridge.token.symbol + ) + if (!toBridgeAssist) { + EventLogger.warn(`To Bridge assist not found`) + return false + } + let oldRwaAssist = false + if ( + toBridgeAssist.token.symbol.toLowerCase() === 'rwa' && + useOldRwaBridge(transaction.timestamp) + ) { + oldRwaAssist = true + } + const toContract = anyBridgeAssist( + oldRwaAssist ? _oldRWABridge : toBridgeAssist.bridgeAddress, + providers[toChainId as ChainId] + ) + const fulfilledAt = await toContract.fulfilledAt( + transaction.fromChain, + transaction.fromUser, + transaction.nonce + ) + return !fulfilledAt.eq(0) + } + + async getAllBridges() { + const bridges = await bridgeInfoRepo.find({}) + return bridges + } +} diff --git a/backend-all/src/services/index.ts b/backend-all/src/services/index.ts new file mode 100644 index 0000000..b712d65 --- /dev/null +++ b/backend-all/src/services/index.ts @@ -0,0 +1,7 @@ +import {BridgeService} from './bridge' +import {TokenService} from './token' + +const tokenService = new TokenService() +const bridgeService = new BridgeService() + +export {tokenService, bridgeService} \ No newline at end of file diff --git a/backend-all/src/services/token.ts b/backend-all/src/services/token.ts new file mode 100644 index 0000000..7ced107 --- /dev/null +++ b/backend-all/src/services/token.ts @@ -0,0 +1,189 @@ +import { ChainId } from '@/gotbit-tools/node/types' +import { tokenRepo } from '@/lib/database' +import EventLogger from '@/lib/logger/index.logger' +import { BRIDGEASSISTS, tokenSymbols } from '@/utils/constant' +import { _getProvider, isSolChain } from '@/utils/helpers' +import { anyToken } from '@/utils/useContracts' +import { providers, utils } from 'ethers' +import { In } from 'typeorm' +import { bridgeService } from '.' +import { clusterApiUrl, Connection, PublicKey } from '@solana/web3.js' +import { getMint } from '@solana/spl-token' + +export class TokenService { + async addToken( + tokenAddress: string, + chainId: ChainId, + provider: providers.JsonRpcProvider + ) { + try { + EventLogger.info(`tokenAddress ${tokenAddress}`) + EventLogger.info(`chain Id ${chainId}`) + const existingToken = await tokenRepo.findOne({ chainId, tokenAddress }) + if (existingToken) { + return existingToken + } + if (tokenAddress === '0x0000000000000000000000000000000000000001') { + const name = chainId === '200810' || chainId === '200901' ? 'Bitcoin' : 'RWA' + const symbol = chainId === '200810' || chainId === '200901' ? 'BTC' : 'RWA' + const decimal = 18 + const newToken = await tokenRepo.create({ + tokenAddress, + chainId, + symbol, + decimal, + name, + }) + await tokenRepo.save(newToken) + return newToken + } + const token = anyToken(tokenAddress, provider) + + const symbolPromise = token.symbol() + const decimalsPromise = token.decimals() + const namePromise = token.name() + let [symbol, decimals, name] = await Promise.all([ + symbolPromise, + decimalsPromise, + namePromise, + ]) + if (symbol.toLowerCase() === 'xrwa'){ + symbol = 'RWA' + } + const newToken = await tokenRepo.create({ + tokenAddress, + chainId, + symbol, + decimal: decimals, + name, + }) + await tokenRepo.save(newToken) + return newToken + } catch (error) { + console.error(error) + throw error + } + } + + async getTokens() { + try { + const chainIds = Object.keys(BRIDGEASSISTS) + const tokens = await tokenRepo.find({ chainId: In(chainIds) }) + return tokens + } catch (error) { + console.error('getTokens error', error) + throw error + } + } + + async seedTokenAndBridges() { + const chainIds = Object.keys(BRIDGEASSISTS) + + Promise.all( + chainIds.map(async (chainId) => { + try { + const isSolanaChain = isSolChain(chainId) + if (isSolanaChain) { + const connection = new Connection( + chainId === 'sol.mainnet' + ? clusterApiUrl('mainnet-beta') + : clusterApiUrl('devnet') + ) + const bridgeAssists: { bridgeAssist: string; token: string }[] = ( + BRIDGEASSISTS as any + )[chainId] + for (let bridgeAssist of bridgeAssists) { + EventLogger.info(`Seeding token ${bridgeAssist.token} on ${chainId}`) + const token = await this.addSolanaToken( + bridgeAssist.token, + chainId as ChainId, + connection + ) + + const bridge = await bridgeService.addSolanaBridge( + bridgeAssist.bridgeAssist, + chainId as ChainId, + token + ) + EventLogger.info(`Done Seeding token ${bridgeAssist.token} on ${chainId}`) + } + return + } + const provider = await _getProvider(chainId as any) + const bridgeAssists: { bridgeAssist: string; token: string }[] = ( + BRIDGEASSISTS as any + )[chainId] + + for (let bridgeAssist of bridgeAssists) { + EventLogger.info(`Seeding token ${bridgeAssist.token} on ${chainId}`) + const token = await this.addToken( + bridgeAssist.token, + chainId as ChainId, + provider + ) + + const bridge = await bridgeService.addBridge( + bridgeAssist.bridgeAssist, + chainId as ChainId, + token, + provider + ) + EventLogger.info(`Done Seeding token ${bridgeAssist.token} on ${chainId}`) + } + EventLogger.info(`Done Seeding tokens on ${chainId}`) + } catch (error: any) { + EventLogger.error(`Error seeding for ${chainId} ${error.message}`) + } + }) + ) + + return { + success: true, + message: 'Tokens seeding in progress', + } + } + + async getTokenBalanceByBlockTag( + userAddress: string, + blockTag: number, + tokenAddress: string, + chainId: ChainId + ) { + try { + const provider = await _getProvider(chainId) + const token = anyToken(tokenAddress, provider) + const balance = await token.balanceOf(userAddress, { blockTag: +blockTag }) + const decimal = await token.decimals() + const balanceWithDecimal = utils.formatUnits(balance, decimal) + return { + tokenAddress, + balance: balanceWithDecimal, + decimal, + chainId, + } + } catch (error) { + console.error(error) + throw error + } + } + + async addSolanaToken(tokenAddress: string, chainId: ChainId, connection: Connection) { + try { + const mintPublicKey = new PublicKey(tokenAddress) + const accountInfo = await getMint(connection, mintPublicKey) + const symbol = (tokenSymbols as any)[tokenAddress] + const newToken = await tokenRepo.create({ + tokenAddress, + chainId, + symbol, + decimal: accountInfo.decimals, + name: symbol, + }) + await tokenRepo.save(newToken) + return newToken + } catch (error) { + console.log('Error adding solana token', error) + throw error + } + } +} diff --git a/backend-all/src/types/index.ts b/backend-all/src/types/index.ts index fea9525..669a0d0 100644 --- a/backend-all/src/types/index.ts +++ b/backend-all/src/types/index.ts @@ -1,4 +1,4 @@ -import {BigNumber, BigNumberish} from 'ethers' +import { BigNumber, BigNumberish } from 'ethers' import { useContracts } from '@/gotbit-tools/node' export interface AuthResponse { access_token: string @@ -68,7 +68,8 @@ export interface GetTransactionSignationDto { fromChain?: string fromUser?: string index?: string - _tokenMint?: string + transactionId?: string + tokenMint?: string } export interface FulfillTxContract { @@ -82,7 +83,7 @@ export interface FulfillTxContract { type BridgeWithAddress = ReturnType['bridgeAssist']> export type TransactionContract = Awaited< -ReturnType + ReturnType >[number] export type ITransaction = { @@ -107,3 +108,31 @@ export type ExtractedTransaction = { block: string confirmationsRequired: string } + +export enum ChainType { + SOLANA = 'solana', + EVM = 'evm', +} + +export interface GetUserTransactionDto { + userAddress: string + chainIds: string + fulfilled: string + page: string + limit: string + forceSync: string +} + +export interface AddTransactionDto { + bridgeId: string + index: string + + userAddress: string + transactionHash?: string +} + +export interface MarkTransactionAsClaimedDto { + transactionId: string + claimTransactionHash: string + toBridgeId: string +} diff --git a/backend-all/src/utils/constant.ts b/backend-all/src/utils/constant.ts index 3480ed6..89e9059 100644 --- a/backend-all/src/utils/constant.ts +++ b/backend-all/src/utils/constant.ts @@ -1,6 +1,7 @@ -import { ChainId } from "@/gotbit-tools/node/types" +import { ChainId } from '@/gotbit-tools/node/types' import { IS_PROD } from '@/gotbit.config' -import {PublicKey} from '@solana/web3.js' +import { isProd } from './env-var' +import { PublicKey } from '@solana/web3.js' export const REAL_CHAIN_IDS: ChainId[] = IS_PROD ? ['97', '421614', '42421', '84532'] @@ -20,202 +21,224 @@ export const eip712Transaction = { ], } - -export const SOLANABRIDGE_TOKENS= { - '5Ff1K9UAT3RWqdZ24qcF3w3UNTvXWkfaqirQgWzgdsYb': "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU" +export const SOLANABRIDGE_TOKENS = { + '5Ff1K9UAT3RWqdZ24qcF3w3UNTvXWkfaqirQgWzgdsYb': + '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU', } -export const BRIDGEASSISTS = -{ - "1": [ - { - bridgeAssist: "0x85FCf4D25895Eeb5306643777F1205331415F51a", - token: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", - }, - { - bridgeAssist: "0x26fa2991f15473B3502D767b49e5805753b8F7F8", - token: "0xdAC17F958D2ee523a2206206994597C13D831ec7", - }, - { - bridgeAssist: "0x1B2322a56f43DBDcB19fcd97527EeB734EEeD119", - token: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", - }, - { - bridgeAssist: "0xc415231cc96d20d99248706403B7580bE560c140", - token: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", - }, - ], - "56": [ - { - bridgeAssist: "0x0FFE2dA242E959a7446Abb56A8f2626D0DC4fce7", - token: "0x55d398326f99059fF775485246999027B3197955", - }, - ], - "8453": [ - { - bridgeAssist: "0x5E007f834b6Ee2fcdA41631AD444b4dAAEc372b0", - token: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", - }, - { - bridgeAssist: "0xEd87e9170152A12a4D3904F5cdE323b35d880858", - token: "0x4200000000000000000000000000000000000006", - }, - ], - "42161": [ - { - bridgeAssist: "0x0FFE2dA242E959a7446Abb56A8f2626D0DC4fce7", - token: "0xAD4b9c1FbF4923061814dD9d5732EB703FaA53D4", - }, - { - bridgeAssist: "0x5116990d844bda038DBD037D943FcB7481b5Fee7", - token: "0x3096e7BFd0878Cc65be71f8899Bc4CFB57187Ba3", - }, - { - bridgeAssist: "0x6377C8cC083d7CEB49fD3eE1244351BFB86C961e", - token: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", - }, - { - bridgeAssist: "0x475d2Ff7955c5359D31B19DC275be3a466f035D5", - token: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", - }, - ], - "42420": [ - { - bridgeAssist: "0xA6c8B33edD4894E42d0C5585fEC52aAC6FF9147d", - token: "0x2B7C1342Cc64add10B2a79C8f9767d2667DE64B2", - }, - { - bridgeAssist: "0x08d4a11Fb4fFE7022deBbBbcBb7444005B09a2FC", - token: "0xDBDc8c7B96286899aB624F6a59dd0250DD4Ce9bC", - }, - // { - // bridgeAssist: "0x4f7C5492919e1dB5Bf667D6397e54B41bB93146c", - // token: "0x0000000000000000000000000000000000000001", - // }, - { - bridgeAssist: "0x14d65D3E8491E51742a237Ce84993897bBA13131", - token: "0x02afe9989D86a0357fbb238579FE035dc17BcAB0", - }, - { - bridgeAssist: "0x8D03A4E2dBfbf13043Bde6278658EFfCE6FE6b02", - token: "0xEc6943BB984AED25eC96986898721a7f8aB6212E", - }, - { - bridgeAssist: "0x196434734f09DFE6D479b5a248a45cfbe516382a", - token: "0x26E490d30e73c36800788DC6d6315946C4BbEa24", - }, - { - bridgeAssist: "0x32cA10Bb1af2535937b8D84aAA6DBfe95dc15A5d", - token: "0xbe231A8492487aAe6096278A97050FAe6B9d5BEc", - }, - { - bridgeAssist: "0x8C1f4a30eAc37071Ec3ce70A86A1C66c5711181d", - token: "0xE59EABcDc3C86909a391D0760b039A3f23d48281", - }, - ], - "200901": [ - { - bridgeAssist: "0xA6c8B33edD4894E42d0C5585fEC52aAC6FF9147d", - token: "0x0000000000000000000000000000000000000001", - }, - ], - "137": [ - { - bridgeAssist: "0x85FCf4D25895Eeb5306643777F1205331415F51a", - token: "0x82a0E6c02b91eC9f6ff943C0A933c03dBaa19689", - }, - { - bridgeAssist: "0x26fa2991f15473B3502D767b49e5805753b8F7F8", - token: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", - }, - { - bridgeAssist: "0x1B2322a56f43DBDcB19fcd97527EeB734EEeD119", - token: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359", - }, - ], - - "42421": [ - { - bridgeAssist: "0x166949B55a62A365DEa45B9149Ac69f69e7E6af7", - token: "0xc83230DFeDfdC3F59Da9B5d3a5c089a66A3d5EBa", - }, - { - bridgeAssist: "0xD05472A955112A6dD70df561C2BD7446879458D5", - token: "0x2F633a89Cf5cd1269b71F095265d708e65d56B89", - }, - // { - // bridgeAssist: "0xb5Dc3E50A3a698059a5fa56B4A0106535c349124", - // token: "0xE8975a94296e3A473c1731E09d687Dda8c437309", - // }, - { - bridgeAssist: "0x58cD62FE7E6c4EBC03dd504B63E36696BB3a2477", - token: "0x6cb8C82DaB692a708D0bbB533aa6A709d4CE6dCA", - }, - { - bridgeAssist: "0xC5e7B562B7f99942Db2B6F265FeFc2a7BBf92C17", - token: "0xc53eb7797Ab27bFbdCa418665fd07665839B2a1d", - }, - // { - // bridgeAssist: "0x16eBe28f15BF37c5066990684F62A2F471698123", - // token: "0x39C6b75fAeAb6B54541BE34860AE6250263377e9", - // }, - { - bridgeAssist: "0xFF91925108094cC5165A41e5b56E3F474a8071eA", - token: "0xc33741fddEBeA854d265db6F9707900Efb0211a2", - }, - { - bridgeAssist: "0xFefbba1Bd5b622f209Af3956FB72E938fa2Dcd0c", - token: "0xdD2A1a924Ceb0b2C48d50c60b36Bb061Fe05f54C", - }, - ], - "84532": [ - { - bridgeAssist: "0xE1c83d0Be5a341120A59507a891Ab007FF5954F0", - token: "0x6cb8C82DaB692a708D0bbB533aa6A709d4CE6dCA", - }, - // { - // bridgeAssist: "0xB8696D46A6172953f03306aDCa7c7CE12dEBA99c", - // token: "0x43f4A3dA572caabADbf17bac588a5Afda9d0D9dd", - // }, - { - bridgeAssist: "0x10ad974526D621667dBaE33E6Fc92Bf711f98054", - token: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", - }, - ], - "200810": [ - { - bridgeAssist: "0xc0ecf31e20521F3b0dA5c2b73Fa6A74A5A0EC236", - token: "0x0000000000000000000000000000000000000001", - }, - ], - "421614": [ - { - bridgeAssist: "0xEC91dd5f2048DB18C32e15Ca75a59e1e72E5E267", - token: "0xCA0010bB0Af1729CA608A966Fcb77c5dbCB7b110", - }, - { - bridgeAssist: "0xD05472A955112A6dD70df561C2BD7446879458D5", - token: "0x2F633a89Cf5cd1269b71F095265d708e65d56B89", - }, - // { - // bridgeAssist: "0xb5Dc3E50A3a698059a5fa56B4A0106535c349124", - // token: "0xE8975a94296e3A473c1731E09d687Dda8c437309", - // }, - { - bridgeAssist: "0x58cD62FE7E6c4EBC03dd504B63E36696BB3a2477", - token: "0x6cb8C82DaB692a708D0bbB533aa6A709d4CE6dCA", - }, - { - bridgeAssist: "0x02C69440Fc8E13d16F9bB53B562ceC405341eFcB", - token: "0x58B202B9650b4e55D9F3f573c25b2930Ba16d0B2", - }, - { - bridgeAssist: "0xDeb5C8A8804eA044A65192A1a3Caa59258bfC4db", - token: "0x01BC26d52a65712987464E75044b0aB9096E9c45", - }, - ], -}; +export const BRIDGEASSISTS = isProd + ? { + '1': [ + { + bridgeAssist: '0x85FCf4D25895Eeb5306643777F1205331415F51a', + token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + }, + { + bridgeAssist: '0x26fa2991f15473B3502D767b49e5805753b8F7F8', + token: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + }, + { + bridgeAssist: '0x1B2322a56f43DBDcB19fcd97527EeB734EEeD119', + token: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + }, + { + bridgeAssist: '0xc415231cc96d20d99248706403B7580bE560c140', + token: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', + }, + ], + '56': [ + { + bridgeAssist: '0x0FFE2dA242E959a7446Abb56A8f2626D0DC4fce7', + token: '0x55d398326f99059fF775485246999027B3197955', + }, + ], + '8453': [ + { + bridgeAssist: '0x5E007f834b6Ee2fcdA41631AD444b4dAAEc372b0', + token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + }, + { + bridgeAssist: '0xEd87e9170152A12a4D3904F5cdE323b35d880858', + token: '0x4200000000000000000000000000000000000006', + }, + ], + '42161': [ + { + bridgeAssist: '0x0FFE2dA242E959a7446Abb56A8f2626D0DC4fce7', + token: '0xAD4b9c1FbF4923061814dD9d5732EB703FaA53D4', + }, + { + bridgeAssist: '0x5116990d844bda038DBD037D943FcB7481b5Fee7', + token: '0x3096e7BFd0878Cc65be71f8899Bc4CFB57187Ba3', + }, + { + bridgeAssist: '0x6377C8cC083d7CEB49fD3eE1244351BFB86C961e', + token: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + }, + { + bridgeAssist: '0x475d2Ff7955c5359D31B19DC275be3a466f035D5', + token: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', + }, + ], + '42420': [ + { + bridgeAssist: '0xA6c8B33edD4894E42d0C5585fEC52aAC6FF9147d', + token: '0x2B7C1342Cc64add10B2a79C8f9767d2667DE64B2', + }, + { + bridgeAssist: '0x08d4a11Fb4fFE7022deBbBbcBb7444005B09a2FC', + token: '0xDBDc8c7B96286899aB624F6a59dd0250DD4Ce9bC', + }, + // { + // bridgeAssist: "0x4f7C5492919e1dB5Bf667D6397e54B41bB93146c", + // token: "0x0000000000000000000000000000000000000001", + // }, + { + bridgeAssist: '0x14d65D3E8491E51742a237Ce84993897bBA13131', + token: '0x02afe9989D86a0357fbb238579FE035dc17BcAB0', + }, + { + bridgeAssist: '0x8D03A4E2dBfbf13043Bde6278658EFfCE6FE6b02', + token: '0xEc6943BB984AED25eC96986898721a7f8aB6212E', + }, + { + bridgeAssist: '0x196434734f09DFE6D479b5a248a45cfbe516382a', + token: '0x26E490d30e73c36800788DC6d6315946C4BbEa24', + }, + { + bridgeAssist: '0x32cA10Bb1af2535937b8D84aAA6DBfe95dc15A5d', + token: '0xbe231A8492487aAe6096278A97050FAe6B9d5BEc', + }, + { + bridgeAssist: '0x8C1f4a30eAc37071Ec3ce70A86A1C66c5711181d', + token: '0xE59EABcDc3C86909a391D0760b039A3f23d48281', + }, + ], + '200901': [ + { + bridgeAssist: '0xA6c8B33edD4894E42d0C5585fEC52aAC6FF9147d', + token: '0x0000000000000000000000000000000000000001', + }, + ], + '137': [ + { + bridgeAssist: '0x85FCf4D25895Eeb5306643777F1205331415F51a', + token: '0x82a0E6c02b91eC9f6ff943C0A933c03dBaa19689', + }, + { + bridgeAssist: '0x26fa2991f15473B3502D767b49e5805753b8F7F8', + token: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', + }, + { + bridgeAssist: '0x1B2322a56f43DBDcB19fcd97527EeB734EEeD119', + token: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', + }, + ], + } + : { + '42421': [ + { + bridgeAssist: '0x166949B55a62A365DEa45B9149Ac69f69e7E6af7', + token: '0xc83230DFeDfdC3F59Da9B5d3a5c089a66A3d5EBa', + }, + { + bridgeAssist: '0xD05472A955112A6dD70df561C2BD7446879458D5', + token: '0x2F633a89Cf5cd1269b71F095265d708e65d56B89', + }, + // { + // bridgeAssist: "0xb5Dc3E50A3a698059a5fa56B4A0106535c349124", + // token: "0xE8975a94296e3A473c1731E09d687Dda8c437309", + // }, + { + bridgeAssist: '0x83390F03F83a110048a5A3AE9EA8a7599d0F3f06', + token: '0x0E69db5966Cea75041B54B114fcFd7Dda2245CE7', + }, + { + bridgeAssist: '0xC5e7B562B7f99942Db2B6F265FeFc2a7BBf92C17', + token: '0xc53eb7797Ab27bFbdCa418665fd07665839B2a1d', + }, + // { + // bridgeAssist: "0x16eBe28f15BF37c5066990684F62A2F471698123", + // token: "0x39C6b75fAeAb6B54541BE34860AE6250263377e9", + // }, + { + bridgeAssist: '0xFF91925108094cC5165A41e5b56E3F474a8071eA', + token: '0xc33741fddEBeA854d265db6F9707900Efb0211a2', + }, + { + bridgeAssist: '0xFefbba1Bd5b622f209Af3956FB72E938fa2Dcd0c', + token: '0xdD2A1a924Ceb0b2C48d50c60b36Bb061Fe05f54C', + }, + ], + '84532': [ + { + bridgeAssist: '0xE1c83d0Be5a341120A59507a891Ab007FF5954F0', + token: '0x6cb8C82DaB692a708D0bbB533aa6A709d4CE6dCA', + }, + // { + // bridgeAssist: "0xB8696D46A6172953f03306aDCa7c7CE12dEBA99c", + // token: "0x43f4A3dA572caabADbf17bac588a5Afda9d0D9dd", + // }, + { + bridgeAssist: '0x10ad974526D621667dBaE33E6Fc92Bf711f98054', + token: '0x036CbD53842c5426634e7929541eC2318f3dCF7e', + }, + ], + '200810': [ + { + bridgeAssist: '0xc0ecf31e20521F3b0dA5c2b73Fa6A74A5A0EC236', + token: '0x0000000000000000000000000000000000000001', + }, + ], + '421614': [ + { + bridgeAssist: '0xEC91dd5f2048DB18C32e15Ca75a59e1e72E5E267', + token: '0xCA0010bB0Af1729CA608A966Fcb77c5dbCB7b110', + }, + { + bridgeAssist: '0xD05472A955112A6dD70df561C2BD7446879458D5', + token: '0x2F633a89Cf5cd1269b71F095265d708e65d56B89', + }, + // { + // bridgeAssist: "0xb5Dc3E50A3a698059a5fa56B4A0106535c349124", + // token: "0xE8975a94296e3A473c1731E09d687Dda8c437309", + // }, + { + bridgeAssist: '0x58cD62FE7E6c4EBC03dd504B63E36696BB3a2477', + token: '0x6cb8C82DaB692a708D0bbB533aa6A709d4CE6dCA', + }, + { + bridgeAssist: '0x02C69440Fc8E13d16F9bB53B562ceC405341eFcB', + token: '0x58B202B9650b4e55D9F3f573c25b2930Ba16d0B2', + }, + { + bridgeAssist: '0xDeb5C8A8804eA044A65192A1a3Caa59258bfC4db', + token: '0x01BC26d52a65712987464E75044b0aB9096E9c45', + }, + ], + 'sol.devnet': [ + { + bridgeAssist: '5Ff1K9UAT3RWqdZ24qcF3w3UNTvXWkfaqirQgWzgdsYb', + token: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU', + }, + { + bridgeAssist: '5Ff1K9UAT3RWqdZ24qcF3w3UNTvXWkfaqirQgWzgdsYb', + token: 'EfdrCGkaPsEBsMKb3DsVSDWHLJ4rpqFBbphXEGaa9gVj', + }, + ], + } export const chainBridgeAssit = { '42420': '0x8D03A4E2dBfbf13043Bde6278658EFfCE6FE6b02', - '42421': '0xFefbba1Bd5b622f209Af3956FB72E938fa2Dcd0c' -} \ No newline at end of file + '42421': '0xFefbba1Bd5b622f209Af3956FB72E938fa2Dcd0c', +} + +export const tokenSymbols = isProd + ? {} + : { + '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU': 'USDC', + EfdrCGkaPsEBsMKb3DsVSDWHLJ4rpqFBbphXEGaa9gVj: 'USDT', + } + +export const _oldRWABridge = isProd + ? '0x4f7C5492919e1dB5Bf667D6397e54B41bB93146c' + : '0xE1c83d0Be5a341120A59507a891Ab007FF5954F0' diff --git a/backend-all/src/utils/env-var.ts b/backend-all/src/utils/env-var.ts index 9144a51..a1870ff 100644 --- a/backend-all/src/utils/env-var.ts +++ b/backend-all/src/utils/env-var.ts @@ -1,11 +1,28 @@ -export const arbitrum_sepolia_rpc= process.env.ARBITRIUM_SEPOLIA_RPC -export const arbitrum_mainnet_rpc= process.env.ARBITRIUM_MAINNET_RPC -export const ethereum_sepolia_rpc= process.env.ETHEREUM_SEPOLIA_RPC -export const ethereum_mainnet_rpc= process.env.ETHEREUM_MAINNET_RPC -export const polygon_amoy_rpc= process.env.POLYGON_AMOY_RPC -export const polygon_mainnet_rpc= process.env.POLYGON_MAINNET_RPC -export const base_spolia_rpc= process.env.BASE_SEPOLIA_RPC -export const base_mainnet_rpc= process.env.BASE_MAINNET_RPC -export const binance_testnet_rpc= process.env.BINANCE_TESTNET_RPC -export const binance_mainnet_rpc= process.env.BINANCE_MAINNET_RPC -export const relayerIndex= process.env.RELAYER_INDEX +export const arbitrum_sepolia_rpc = process.env.ARBITRIUM_SEPOLIA_RPC +export const arbitrum_mainnet_rpc = process.env.ARBITRIUM_MAINNET_RPC +export const ethereum_sepolia_rpc = process.env.ETHEREUM_SEPOLIA_RPC +export const ethereum_mainnet_rpc = process.env.ETHEREUM_MAINNET_RPC +export const polygon_amoy_rpc = process.env.POLYGON_AMOY_RPC +export const polygon_mainnet_rpc = process.env.POLYGON_MAINNET_RPC +export const base_spolia_rpc = process.env.BASE_SEPOLIA_RPC +export const base_mainnet_rpc = process.env.BASE_MAINNET_RPC +export const binance_testnet_rpc = process.env.BINANCE_TESTNET_RPC +export const binance_mainnet_rpc = process.env.BINANCE_MAINNET_RPC +export const relayerIndex = process.env.RELAYER_INDEX +export const isProd = process.env.PROD === 'true' +export const isPublicRelayer = process.env.IS_PUBLIC_RELAYER === 'true' + +// export const arbitrum_sepolia_ws_rpc = process.env.ARBITRIUM_SEPOLIA_WS_RPC +// export const arbitrum_mainnet_ws_rpc = process.env.ARBITRIUM_MAINNET_WS_RPC +// export const ethereum_sepolia_ws_rpc = process.env.ETHEREUM_SEPOLIA_WS_RPC +// export const ethereum_mainnet_ws_rpc = process.env.ETHEREUM_MAINNET_WS_RPC +// export const polygon_amoy_ws_rpc = process.env.POLYGON_AMOY_WS_RPC +// export const polygon_mainnet_ws_rpc = process.env.POLYGON_MAINNET_WS_RPC +// export const base_spolia_ws_rpc = process.env.BASE_SEPOLIA_WS_RPC +// export const base_mainnet_ws_rpc = process.env.BASE_MAINNET_WS_RPC +// export const binance_testnet_ws_rpc = process.env.BINANCE_TESTNET_WS_RPC +// export const binance_mainnet_ws_rpc = process.env.BINANCE_MAINNET_WS_RPC +// export const bitlayer_testnet_ws_rpc = process.env.BITLAYER_TESTNET_WS_RPC +// export const bitlayer_mainnet_ws_rpc = process.env.BITLAYER_MAINNET_WS_RPC +// export const assetchain_testnet_ws_rpc = process.env.ASSETCHAIN_TESTNET_WS_RPC +// export const assetchain_mainnet_ws_rpc = process.env.ASSETCHAIN_MAINNET_WS_RPC diff --git a/backend-all/src/utils/helpers.ts b/backend-all/src/utils/helpers.ts index 535339d..0732a02 100644 --- a/backend-all/src/utils/helpers.ts +++ b/backend-all/src/utils/helpers.ts @@ -12,7 +12,7 @@ import { polygon_mainnet_rpc, relayerIndex, } from './env-var' -import { BigNumber, providers } from 'ethers' +import { BigNumber, providers, utils } from 'ethers' import { universalRpc } from '@/gotbit-tools/node/rpc' import { getChainName, getChainTag } from '@/gotbit-tools/node' import { getConfirmationsRequired } from './solana/helpers' @@ -106,6 +106,7 @@ const _rpc = universalRpc() export async function _getProvider(chainId: ChainId) { let rpc: string | null = '' const rpcListString = getChainRPCS(chainId) + console.log(rpcListString,'list', chainId) if (rpcListString) { const rpcList = rpcListString.split(',') rpc = await getActiveRpc(rpcList) @@ -115,11 +116,11 @@ export async function _getProvider(chainId: ChainId) { } else { rpc = _rpc(getChainTag(chainId)) console.log(rpc, chainId, 'kdkdk') - if (!rpc) throw new Error(`Relayer ${relayerIndex} Rpc error. Please try again later`) + if (!rpc) throw new Error(`Relayer ${relayerIndex} Rpc error on ${chainId}. Please try again later`) rpc = await getActiveRpc([rpc]) console.log(`Using RPC public RPC`) } - if (!rpc) throw new Error(`Relayer ${relayerIndex} Rpc error. Please try again later`) + if (!rpc) throw new Error(`Relayer ${relayerIndex} Rpc error on ${chainId}. Please try again later`) return new providers.JsonRpcProvider(rpc) } @@ -127,3 +128,22 @@ export async function hasPassedConfirmationEvm(provider: providers.JsonRpcProvid const blockNumber = await provider.getBlockNumber() return BigNumber.from(blockNumber).gt(block.add(getConfirmationsRequired(fromChain))) } + +export function isSolChain(chainId: string){ + return chainId.includes('sol') +} + +export function isEvmAddress(address: string){ + return utils.isAddress(address) +} + +export function useOldRwaBridge(timestamp: BigNumber): boolean { + // Create cutoff date (June 26, 2025 UTC) + const cutoffDate = new Date("2025-06-25T00:00:00Z"); + + // Compare the timestamps directly as numbers + const timestampMs = Number(timestamp.toString()) * 1000; + const cutoffMs = cutoffDate.getTime(); + + return timestampMs < cutoffMs; +} diff --git a/backend-all/src/utils/solana/helpers.ts b/backend-all/src/utils/solana/helpers.ts index 97276d6..de308dc 100644 --- a/backend-all/src/utils/solana/helpers.ts +++ b/backend-all/src/utils/solana/helpers.ts @@ -52,13 +52,12 @@ export const solanaWorkspace = (bridgeAssist: string, tokenMint: string) => { const network = clusterApiUrl(isMain ? 'mainnet-beta' : 'devnet') const connection = new Connection(network, 'confirmed') - const provider = new AnchorProvider(connection, new NodeWallet(owner), { + const provider = new AnchorProvider(connection as any, new NodeWallet(owner as any), { preflightCommitment: 'confirmed', }) const program = new Program(IDL, provider) if (!tokenMint) throw new Error(`Token mint not initialized`) - return { payer: owner, owner, @@ -346,8 +345,6 @@ export async function getSolanaSendTx( if (!sendTxAccount) throw new Error(`Transaction not found with nonce ${nonce}`) - console.log(sendTxAccount.toChain.byte, 'ssk') - const tx: ITransaction = { fromUser: user.toString(), toUser: '0x' + Buffer.from(sendTxAccount.to.byte).toString('hex').slice(0, 40), diff --git a/backend-all/tsconfig.json b/backend-all/tsconfig.json index 06d9017..8b3a856 100644 --- a/backend-all/tsconfig.json +++ b/backend-all/tsconfig.json @@ -12,7 +12,10 @@ "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, - "skipLibCheck": true + "skipLibCheck": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "strictPropertyInitialization": false }, "exclude": ["./vitest.config.ts"] } diff --git a/backend-all/yarn.lock b/backend-all/yarn.lock index 510627f..1b20141 100644 --- a/backend-all/yarn.lock +++ b/backend-all/yarn.lock @@ -311,6 +311,11 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@colors/colors@1.6.0", "@colors/colors@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0" + integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA== + "@coral-xyz/anchor-errors@^0.31.1": version "0.31.1" resolved "https://registry.yarnpkg.com/@coral-xyz/anchor-errors/-/anchor-errors-0.31.1.tgz#d635cbac2533973ae6bfb5d3ba1de89ce5aece2d" @@ -343,6 +348,15 @@ bn.js "^5.1.2" buffer-layout "^1.2.0" +"@dabh/diagnostics@^2.0.2": + version "2.0.8" + resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.8.tgz#ead97e72ca312cf0e6dd7af0d300b58993a31a5e" + integrity sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q== + dependencies: + "@so-ric/colorspace" "^1.1.6" + enabled "2.0.x" + kuler "^2.0.0" + "@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" @@ -685,6 +699,18 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -942,6 +968,11 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a" integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + "@sinclair/typebox@^0.25.16": version "0.25.24" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" @@ -961,6 +992,14 @@ dependencies: "@sinonjs/commons" "^3.0.0" +"@so-ric/colorspace@^1.1.6": + version "1.1.6" + resolved "https://registry.yarnpkg.com/@so-ric/colorspace/-/colorspace-1.1.6.tgz#62515d8b9f27746b76950a83bde1af812d91923b" + integrity sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw== + dependencies: + color "^5.0.2" + text-hex "1.0.x" + "@solana/buffer-layout-utils@^0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz#b45a6cab3293a2eb7597cceb474f229889d875ca" @@ -1089,7 +1128,7 @@ "@solana/spl-token-metadata" "^0.1.6" buffer "^6.0.3" -"@solana/web3.js@^1.32.0", "@solana/web3.js@^1.69.0", "@solana/web3.js@^1.98.2": +"@solana/web3.js@^1.32.0", "@solana/web3.js@^1.69.0": version "1.98.2" resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.98.2.tgz#45167a5cfb64436944bf4dc1e8be8482bd6d4c14" integrity sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A== @@ -1110,6 +1149,32 @@ rpc-websockets "^9.0.2" superstruct "^2.0.2" +"@solana/web3.js@^1.98.4": + version "1.98.4" + resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.98.4.tgz#df51d78be9d865181ec5138b4e699d48e6895bbe" + integrity sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw== + dependencies: + "@babel/runtime" "^7.25.0" + "@noble/curves" "^1.4.2" + "@noble/hashes" "^1.4.0" + "@solana/buffer-layout" "^4.0.1" + "@solana/codecs-numbers" "^2.1.0" + agentkeepalive "^4.5.0" + bn.js "^5.2.1" + borsh "^0.7.0" + bs58 "^4.0.1" + buffer "6.0.3" + fast-stable-stringify "^1.0.0" + jayson "^4.1.1" + node-fetch "^2.7.0" + rpc-websockets "^9.0.2" + superstruct "^2.0.2" + +"@sqltools/formatter@^1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.5.tgz#3abc203c79b8c3e90fd6c156a0c62d5403520e12" + integrity sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw== + "@swc/helpers@^0.5.11": version "0.5.17" resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.17.tgz#5a7be95ac0f0bf186e7e6e890e7a6f6cda6ce971" @@ -1280,6 +1345,15 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== +"@types/pg@^8.6.6": + version "8.15.5" + resolved "https://registry.yarnpkg.com/@types/pg/-/pg-8.15.5.tgz#ef43e0f33b62dac95cae2f042888ec7980b30c09" + integrity sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ== + dependencies: + "@types/node" "*" + pg-protocol "*" + pg-types "^2.2.0" + "@types/prettier@^2.1.5": version "2.7.3" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" @@ -1331,6 +1405,11 @@ dependencies: "@types/superagent" "*" +"@types/triple-beam@^1.3.2": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c" + integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw== + "@types/uuid@^8.3.4": version "8.3.4" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" @@ -1399,6 +1478,11 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.2.2" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1" + integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg== + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -1418,6 +1502,16 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +ansi-styles@^6.1.0: + version "6.2.3" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.3.tgz#c044d5dcc521a076413472597a1acb1f103c4041" + integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg== + +ansis@^3.17.0: + version "3.17.0" + resolved "https://registry.yarnpkg.com/ansis/-/ansis-3.17.0.tgz#fa8d9c2a93fe7d1177e0c17f9eeb562a58a832d7" + integrity sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg== + anymatch@^3.0.3, anymatch@~3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" @@ -1426,6 +1520,11 @@ anymatch@^3.0.3, anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +app-root-path@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.1.0.tgz#5971a2fc12ba170369a7a1ef018c71e6e47c2e86" + integrity sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -1453,11 +1552,23 @@ assertion-error@^1.1.0: resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== +async@^3.2.3: + version "3.2.6" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" + integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" + axios@^0.27.2: version "0.27.2" resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" @@ -1762,6 +1873,14 @@ c8@^7.11.3: yargs "^16.2.0" yargs-parser "^20.2.9" +call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + call-bind@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -1770,6 +1889,24 @@ call-bind@^1.0.0: function-bind "^1.1.1" get-intrinsic "^1.0.2" +call-bind@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c" + integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== + dependencies: + call-bind-apply-helpers "^1.0.0" + es-define-property "^1.0.0" + get-intrinsic "^1.2.4" + set-function-length "^1.2.2" + +call-bound@^1.0.3, call-bound@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" + integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== + dependencies: + call-bind-apply-helpers "^1.0.2" + get-intrinsic "^1.3.0" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1902,16 +2039,43 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" +color-convert@^3.0.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-3.1.2.tgz#cef9e0fd4cb90b07c14697b3fa70af9d7f4870f1" + integrity sha512-UNqkvCDXstVck3kdowtOTWROIJQwafjOfXSmddoDrXo4cewMKmusCeF22Q24zvjR8nwWib/3S/dfyzPItPEiJg== + dependencies: + color-name "^2.0.0" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color-name@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-2.0.2.tgz#85054825a23e6d6f81d3503f660c4c4a2a15f04f" + integrity sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A== + color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-string@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-2.1.2.tgz#db1dd52414cc9037ada8fa7d936b8e9f6c3366c9" + integrity sha512-RxmjYxbWemV9gKu4zPgiZagUxbH3RQpEIO77XoSSX0ivgABDZ+h8Zuash/EMFLTI4N9QgFPOJ6JQpPZKFxa+dA== + dependencies: + color-name "^2.0.0" + +color@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/color/-/color-5.0.2.tgz#712ec894007ab27b37207732d182784e001b4a3d" + integrity sha512-e2hz5BzbUPcYlIRHo8ieAhYgoajrJr+hWoceg6E345TPsATMUKqDgzt8fSXZJJbxfpiPzkWyphz8yn8At7q3fA== + dependencies: + color-convert "^3.0.1" + color-string "^2.0.0" + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -2020,6 +2184,15 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +cross-spawn@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + date-fns@^2.29.1: version "2.30.0" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" @@ -2032,6 +2205,11 @@ dateformat@^3.0.3: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== +dayjs@^1.11.13: + version "1.11.18" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.18.tgz#835fa712aac52ab9dec8b1494098774ed7070a11" + integrity sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA== + debounce@^1.0.0: version "1.2.1" resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" @@ -2051,6 +2229,13 @@ debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.4: dependencies: ms "2.1.2" +debug@^4.4.0: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + decamelize@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" @@ -2061,6 +2246,11 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== +dedent@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.7.0.tgz#c1f9445335f0175a96587be245a282ff451446ca" + integrity sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ== + deep-eql@^4.1.2: version "4.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" @@ -2073,6 +2263,15 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + delay@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" @@ -2121,6 +2320,20 @@ dotenv@^16.0.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.1.4.tgz#67ac1a10cd9c25f5ba604e4e08bc77c0ebe0ca8c" integrity sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw== +dotenv@^16.4.7: + version "16.6.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.6.1.tgz#773f0e69527a8315c7285d5ee73c4459d20a8020" + integrity sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow== + +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" + dynamic-dedupe@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz#06e44c223f5e4e94d78ef9db23a6515ce2f962a1" @@ -2128,6 +2341,11 @@ dynamic-dedupe@^0.3.0: dependencies: xtend "^4.0.0" +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -2161,6 +2379,16 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +enabled@2.0.x: + version "2.0.0" + resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" + integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -2173,6 +2401,23 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +es-define-property@^1.0.0, es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" + integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== + dependencies: + es-errors "^1.3.0" + es6-promise@^4.0.3: version "4.2.8" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" @@ -2373,6 +2618,11 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fecha@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" + integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw== + file-uri-to-path@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" @@ -2426,11 +2676,23 @@ flat@^5.0.2: resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== +fn.name@1.x.x: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" + integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== + follow-redirects@^1.14.9: version "1.15.2" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== +for-each@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47" + integrity sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg== + dependencies: + is-callable "^1.2.7" + foreground-child@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-2.0.0.tgz#71b32800c9f15aa8f2f83f4a6bd9bff35d861a53" @@ -2439,6 +2701,14 @@ foreground-child@^2.0.0: cross-spawn "^7.0.0" signal-exit "^3.0.2" +foreground-child@^3.1.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f" + integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== + dependencies: + cross-spawn "^7.0.6" + signal-exit "^4.0.1" + form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -2483,6 +2753,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -2508,11 +2783,35 @@ get-intrinsic@^1.0.2: has-proto "^1.0.1" has-symbols "^1.0.3" +get-intrinsic@^1.2.4, get-intrinsic@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== + dependencies: + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== + dependencies: + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" + get-stream@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" @@ -2537,6 +2836,18 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^10.4.5: + version "10.4.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" + glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -2554,6 +2865,11 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +gopd@^1.0.1, gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== + graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" @@ -2574,6 +2890,13 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + has-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" @@ -2584,6 +2907,18 @@ has-symbols@^1.0.3: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== + +has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -2599,6 +2934,13 @@ hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" +hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + he@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" @@ -2706,6 +3048,11 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" +is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + is-core-module@^2.11.0: version "2.12.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" @@ -2755,6 +3102,13 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +is-typed-array@^1.1.14: + version "1.1.15" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b" + integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ== + dependencies: + which-typed-array "^1.1.16" + is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" @@ -2767,6 +3121,11 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2819,6 +3178,15 @@ istanbul-reports@^3.1.3, istanbul-reports@^3.1.4: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jayson@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/jayson/-/jayson-4.2.0.tgz#b71762393fa40bc9637eaf734ca6f40d3b8c0c93" @@ -3248,6 +3616,11 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +kuler@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" + integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== + leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -3290,6 +3663,18 @@ log-symbols@4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" +logform@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/logform/-/logform-2.7.0.tgz#cfca97528ef290f2e125a08396805002b2d060d1" + integrity sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ== + dependencies: + "@colors/colors" "1.6.0" + "@types/triple-beam" "^1.3.2" + fecha "^4.2.0" + ms "^2.1.1" + safe-stable-stringify "^2.3.1" + triple-beam "^1.3.0" + loupe@^2.3.1: version "2.3.6" resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53" @@ -3297,6 +3682,11 @@ loupe@^2.3.1: dependencies: get-func-name "^2.0.0" +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -3330,6 +3720,11 @@ makeerror@1.0.12: dependencies: tmpl "1.0.5" +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -3409,11 +3804,23 @@ minimatch@^3.0.4, minimatch@^3.1.1: dependencies: brace-expansion "^1.1.7" +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + mocha@^10.0.0: version "10.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" @@ -3472,7 +3879,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.0.0: +ms@2.1.3, ms@^2.0.0, ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -3588,6 +3995,13 @@ once@^1.3.0, once@^1.4.0: dependencies: wrappy "1" +one-time@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" + integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== + dependencies: + fn.name "1.x.x" + onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" @@ -3628,6 +4042,11 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +package-json-from-dist@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== + pako@^2.0.3: version "2.1.0" resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" @@ -3668,6 +4087,14 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" @@ -3678,6 +4105,62 @@ pathval@^1.1.1: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== +pg-cloudflare@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz#a1f3d226bab2c45ae75ea54d65ec05ac6cfafbef" + integrity sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg== + +pg-connection-string@^2.9.1: + version "2.9.1" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.9.1.tgz#bb1fd0011e2eb76ac17360dc8fa183b2d3465238" + integrity sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w== + +pg-int8@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" + integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== + +pg-pool@^3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.10.1.tgz#481047c720be2d624792100cac1816f8850d31b2" + integrity sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg== + +pg-protocol@*, pg-protocol@^1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.10.3.tgz#ac9e4778ad3f84d0c5670583bab976ea0a34f69f" + integrity sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ== + +pg-types@2.2.0, pg-types@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" + integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== + dependencies: + pg-int8 "1.0.1" + postgres-array "~2.0.0" + postgres-bytea "~1.0.0" + postgres-date "~1.0.4" + postgres-interval "^1.1.0" + +pg@^8.8.0: + version "8.16.3" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.16.3.tgz#160741d0b44fdf64680e45374b06d632e86c99fd" + integrity sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw== + dependencies: + pg-connection-string "^2.9.1" + pg-pool "^3.10.1" + pg-protocol "^1.10.3" + pg-types "2.2.0" + pgpass "1.0.5" + optionalDependencies: + pg-cloudflare "^1.2.7" + +pgpass@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" + integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== + dependencies: + split2 "^4.1.0" + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -3700,6 +4183,33 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +possible-typed-array-names@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz#93e3582bc0e5426586d9d07b79ee40fc841de4ae" + integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg== + +postgres-array@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" + integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== + +postgres-bytea@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" + integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== + +postgres-date@~1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" + integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== + +postgres-interval@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" + integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== + dependencies: + xtend "^4.0.0" + pretty-format@^29.0.0, pretty-format@^29.5.0: version "29.5.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.5.0.tgz#283134e74f70e2e3e7229336de0e4fce94ccde5a" @@ -3781,6 +4291,15 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== +readable-stream@^3.4.0, readable-stream@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -3788,6 +4307,11 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +reflect-metadata@^0.1.13: + version "0.1.14" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.14.tgz#24cf721fe60677146bb77eeb0e1f9dece3d65859" + integrity sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A== + regenerator-runtime@^0.13.11: version "0.13.11" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" @@ -3859,11 +4383,16 @@ safe-buffer@5.1.2: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-stable-stringify@^2.3.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz#4ca2f8e385f2831c432a719b108a3bf7af42a1dd" + integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA== + "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -3922,11 +4451,32 @@ serve-static@1.15.0: parseurl "~1.3.3" send "0.18.0" +set-function-length@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== +sha.js@^2.4.12: + version "2.4.12" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.12.tgz#eb8b568bf383dfd1867a32c3f2b74eb52bdbf23f" + integrity sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w== + dependencies: + inherits "^2.0.4" + safe-buffer "^5.2.1" + to-buffer "^1.2.0" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -3963,6 +4513,11 @@ signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -3991,11 +4546,26 @@ spawn-command@^0.0.2-1: resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" integrity sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg== +split2@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +sql-highlight@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/sql-highlight/-/sql-highlight-6.1.0.tgz#e34024b4c6eac2744648771edfe3c1f894153743" + integrity sha512-ed7OK4e9ywpE7pgRMkMQmZDPKSVdm0oX5IEtZiKnFucSF0zu6c80GZBe38UqHuVhTWJ9xsKgSMjCG2bml86KvA== + +stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== + stack-utils@^2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" @@ -4028,6 +4598,15 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" @@ -4037,6 +4616,29 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -4044,6 +4646,13 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-ansi@^7.0.1: + version "7.1.2" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.2.tgz#132875abde678c7ea8d691533f2e7e22bb744dba" + integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA== + dependencies: + ansi-regex "^6.0.1" + strip-bom@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" @@ -4133,11 +4742,25 @@ text-encoding-utf-8@^1.0.2: resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== +text-hex@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" + integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== +to-buffer@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.2.2.tgz#ffe59ef7522ada0a2d1cb5dfe03bb8abc3cdc133" + integrity sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw== + dependencies: + isarray "^2.0.5" + safe-buffer "^5.2.1" + typed-array-buffer "^1.0.3" + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -4170,6 +4793,11 @@ tree-kill@^1.2.2: resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== +triple-beam@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984" + integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg== + ts-jest@^29.0.0: version "29.1.0" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.0.tgz#4a9db4104a49b76d2b368ea775b6c9535c603891" @@ -4189,7 +4817,7 @@ tslib@^2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913" integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== -tslib@^2.8.0: +tslib@^2.8.0, tslib@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -4212,6 +4840,35 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typed-array-buffer@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz#a72395450a4869ec033fd549371b47af3a2ee536" + integrity sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw== + dependencies: + call-bound "^1.0.3" + es-errors "^1.3.0" + is-typed-array "^1.1.14" + +typeorm@^0.3.12: + version "0.3.27" + resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.27.tgz#f1e8f3cdc820225f168e901e7e1eaca3a3ec6f3c" + integrity sha512-pNV1bn+1n8qEe8tUNsNdD8ejuPcMAg47u2lUGnbsajiNUr3p2Js1XLKQjBMH0yMRMDfdX8T+fIRejFmIwy9x4A== + dependencies: + "@sqltools/formatter" "^1.2.5" + ansis "^3.17.0" + app-root-path "^3.1.0" + buffer "^6.0.3" + dayjs "^1.11.13" + debug "^4.4.0" + dedent "^1.6.0" + dotenv "^16.4.7" + glob "^10.4.5" + sha.js "^2.4.12" + sql-highlight "^6.0.0" + tslib "^2.8.1" + uuid "^11.1.0" + yargs "^17.7.2" + typescript@^5.0.0: version "5.8.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" @@ -4237,11 +4894,21 @@ utf-8-validate@^5.0.2: dependencies: node-gyp-build "^4.3.0" +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== +uuid@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-11.1.0.tgz#9549028be1753bb934fc96e2bca09bb4105ae912" + integrity sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A== + uuid@^8.3.0, uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" @@ -4281,6 +4948,19 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" +which-typed-array@^1.1.16: + version "1.1.19" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.19.tgz#df03842e870b6b88e117524a4b364b6fc689f956" + integrity sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.8" + call-bound "^1.0.4" + for-each "^0.3.5" + get-proto "^1.0.1" + gopd "^1.2.0" + has-tostringtag "^1.0.2" + which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -4288,11 +4968,46 @@ which@^2.0.1, which@^2.0.2: dependencies: isexe "^2.0.0" +winston-transport@^4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.9.0.tgz#3bba345de10297654ea6f33519424560003b3bf9" + integrity sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A== + dependencies: + logform "^2.7.0" + readable-stream "^3.6.2" + triple-beam "^1.3.0" + +winston@^3.17.0: + version "3.17.0" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.17.0.tgz#74b8665ce9b4ea7b29d0922cfccf852a08a11423" + integrity sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw== + dependencies: + "@colors/colors" "^1.6.0" + "@dabh/diagnostics" "^2.0.2" + async "^3.2.3" + is-stream "^2.0.0" + logform "^2.7.0" + one-time "^1.0.0" + readable-stream "^3.4.0" + safe-stable-stringify "^2.3.1" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.9.0" + workerpool@6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -4302,6 +5017,15 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -4388,7 +5112,7 @@ yargs@16.2.0, yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@^17.3.1: +yargs@^17.3.1, yargs@^17.7.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== From 78d9ee6199cf27438bc9a8c1ad7f8ccad3f064f2 Mon Sep 17 00:00:00 2001 From: Stephen Udeh Date: Sat, 11 Oct 2025 11:58:57 +0100 Subject: [PATCH 16/19] symbol check for USDT --- backend-all/src/services/token.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend-all/src/services/token.ts b/backend-all/src/services/token.ts index 7ced107..677871b 100644 --- a/backend-all/src/services/token.ts +++ b/backend-all/src/services/token.ts @@ -50,6 +50,7 @@ export class TokenService { if (symbol.toLowerCase() === 'xrwa'){ symbol = 'RWA' } + if (symbol === "USD₮0" || symbol === "USDT0") symbol = "USDT"; const newToken = await tokenRepo.create({ tokenAddress, chainId, From b7ddabd2d0503c24f1ff0fdfa83dd4b7bf58b5d8 Mon Sep 17 00:00:00 2001 From: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> Date: Wed, 15 Oct 2025 11:03:38 +0100 Subject: [PATCH 17/19] worked on getting balance and block fromapi (#96) --- backend-all/src/confirmations.json | 42 ++--- backend-all/src/routes/get-blocks.ts | 24 +++ backend-all/src/routes/tokens/index.ts | 26 ++- .../src/routes/tokens/token-allowance.ts | 29 ++++ backend-all/src/services/blockchain.ts | 20 ++- backend-all/src/services/bridge.ts | 11 +- backend-all/src/services/token.ts | 159 +++++++++++++++++- backend-all/src/types/index.ts | 21 +++ backend-all/src/utils/solana/helpers.ts | 4 + 9 files changed, 303 insertions(+), 33 deletions(-) create mode 100644 backend-all/src/routes/get-blocks.ts create mode 100644 backend-all/src/routes/tokens/token-allowance.ts diff --git a/backend-all/src/confirmations.json b/backend-all/src/confirmations.json index f84aa10..7d222f6 100644 --- a/backend-all/src/confirmations.json +++ b/backend-all/src/confirmations.json @@ -1,25 +1,25 @@ { - "1": 7, - "97": 42, - "56": 42, - "137": 42, - "369": 42, - "5000": 42, - "31337": 42, - "42161": 42, - "5001": 42, - "43113": 42, - "80001": 42, - "421614": 42, - "8453": 42, + "1": 10, + "97": 10, + "56": 10, + "137": 10, + "369": 10, + "5000": 10, + "31337": 10, + "42161": 10, + "5001": 10, + "43113": 10, + "80001": 10, + "421614": 10, + "8453": 10, "42421": 5, - "80002": 42, - "84532": 42, - "11155111": 42, - "200810": 42, - "200901": 42, + "80002": 10, + "84532": 10, + "11155111": 10, + "200810": 10, + "200901": 10, "42420": 5, - "solana": 100, - "sol.devnet": 100, - "sol.mainnet": 100 + "solana": 10, + "sol.devnet": 10, + "sol.mainnet": 10 } diff --git a/backend-all/src/routes/get-blocks.ts b/backend-all/src/routes/get-blocks.ts new file mode 100644 index 0000000..4828dfb --- /dev/null +++ b/backend-all/src/routes/get-blocks.ts @@ -0,0 +1,24 @@ +import {query, type Request } from 'express' +import type { Resource } from 'express-automatic-routes' + +import { getBlockNumber } from '@/services/blockchain' +import { ChainId } from '@/gotbit-tools/node/types' +// import axios from 'axios' + +export default (): Resource => ({ + async get(req: Request<{}, {}, {}, { }>, res) { + try { + const chainIds : string = (req.query as any).chainIds + + if (!chainIds) return res.status(400).send('chainIds not specified') + + const chainIdsArray = chainIds.split(',') + + const blockNumbers = await getBlockNumber(chainIdsArray as ChainId[]) + + res.status(200).json({ success: true, data: blockNumbers }) + } catch (error: any) { + res.status(400).json({ error: error.message }) + } + }, +}) diff --git a/backend-all/src/routes/tokens/index.ts b/backend-all/src/routes/tokens/index.ts index 891bbc5..149b8ac 100644 --- a/backend-all/src/routes/tokens/index.ts +++ b/backend-all/src/routes/tokens/index.ts @@ -1,12 +1,12 @@ import { type Request } from 'express' import type { Resource } from 'express-automatic-routes' import { tokenService } from '@/services' +import { GetTokenBalances } from '@/types' // import axios from 'axios' export default (): Resource => ({ async get(req: Request<{}, {}, {}, {}>, res) { try { - const response = await tokenService.getTokens() res.status(200).json({ success: true, @@ -16,4 +16,28 @@ export default (): Resource => ({ res.status(400).json({ error: error.message }) } }, + + async post(req: Request<{}, {}, GetTokenBalances>, res) { + try { + if (!req.body.evmAddress) { + req.body.evmAddress = '' + } + if (!req.body.solanaAddress) { + req.body.solanaAddress = '' + } + if (!req.body.tokens) return res.status(400).json({ error: 'tokens is required' }) + if (!req.body.tokens.length) return res.status(400).json({ error: 'tokens is required' }) + const response = await tokenService.getTokenBalance( + req.body.evmAddress, + req.body.solanaAddress, + req.body.tokens + ) + res.status(200).json({ + success: true, + data: response, + }) + } catch (error: any) { + res.status(400).json({ error: error.message }) + } + }, }) diff --git a/backend-all/src/routes/tokens/token-allowance.ts b/backend-all/src/routes/tokens/token-allowance.ts new file mode 100644 index 0000000..8b7beb6 --- /dev/null +++ b/backend-all/src/routes/tokens/token-allowance.ts @@ -0,0 +1,29 @@ +import { tokenService } from '@/services' +import { type Request } from 'express' +import { Resource } from 'express-automatic-routes' +import { ChainId } from '@/gotbit-tools/node/types' +import { GetTokenAllowance } from '@/types' + +export default (): Resource => ({ + async get(req: Request<{}, {}, {}, any>, res) { + try { + const { evmAddress, spenderAddress, tokenAddress, chainId } = req.query + if (!evmAddress) return res.status(400).json({ error: 'evmAddress is required' }) + if (!spenderAddress) + return res.status(400).json({ error: 'spenderAddress is required' }) + if (!tokenAddress) + return res.status(400).json({ error: 'tokenAddress is required' }) + if (!chainId) return res.status(400).json({ error: 'chainId is required' }) + const response = await tokenService.getTokenAllowance(evmAddress, spenderAddress, { + tokenAddress, + chainId: chainId as ChainId, + }) + res.status(200).json({ + success: true, + data: response, + }) + } catch (error: any) { + res.status(400).json({ error: error.message }) + } + }, +}) diff --git a/backend-all/src/services/blockchain.ts b/backend-all/src/services/blockchain.ts index 0ccc470..fdf70ca 100644 --- a/backend-all/src/services/blockchain.ts +++ b/backend-all/src/services/blockchain.ts @@ -17,6 +17,7 @@ import { getAssociatedTokenAddress, getConfirmationsRequired, getOrCreateAssociatedTokenAccount, + getSolanaConnection, getSolanaSendTx, hasPassedConfirmationSolana, isToSolanaTxFulfilled, @@ -24,7 +25,7 @@ import { solanaWorkspace, } from '@/utils/solana/helpers' import { Connection, PublicKey, Transaction } from '@solana/web3.js' -import { _getProvider, hasPassedConfirmationEvm } from '@/utils/helpers' +import { _getProvider, hasPassedConfirmationEvm, isSolChain } from '@/utils/helpers' import { anyBridgeAssist, anyToken } from '@/utils/useContracts' import { relayerIndex } from '@/utils/env-var' import { BridgeAssist, Token } from '@/contracts/typechain' @@ -376,6 +377,23 @@ async function fulfilledInfo(tx: TransactionContract, bridgeAddress: string) { } } +// get block number by chainId, param is list of chainIds should be in promise.all +export const getBlockNumber = async (chainIds: ChainId[]) => { + const blockNumbers : any= {} + await Promise.all(chainIds.map(async (chainId) => { + if (isSolChain(chainId)) { + const connection = getSolanaConnection(chainId) + const blockNumber = await connection.getSlot() + blockNumbers[chainId] = +blockNumber.toString() + return + } + const provider = await _getProvider(chainId) + const blockNumber = await provider.getBlockNumber() + blockNumbers[chainId] = +blockNumber.toString() + })) + return blockNumbers +} + export type ARB_CHAINID = '42161' | '421614' export const targetBlockNumber = (chainId: ChainId) => chainId === '42161' ? 370576662 : 180981641 diff --git a/backend-all/src/services/bridge.ts b/backend-all/src/services/bridge.ts index bd6655e..1fe3234 100644 --- a/backend-all/src/services/bridge.ts +++ b/backend-all/src/services/bridge.ts @@ -15,7 +15,7 @@ import { BigNumber, providers } from 'ethers' import CONFIRMATIONS from '../confirmations.json' import { Transaction } from '@/lib/database/entities/Transaction' import EventLogger from '@/lib/logger/index.logger' -import { clusterApiUrl, Connection, PublicKey } from '@solana/web3.js' +import { PublicKey } from '@solana/web3.js' import { CHAIN_TO_BUFFER, getSolanaSendTx, @@ -507,7 +507,7 @@ export class BridgeService { if (!bridgeInfo) throw new Error(`Bridge not found`) const chainId = bridgeInfo.chainId if (isSolChain(chainId)) { - const { owner, tokenMint, program, connection } = solanaWorkspace( + const { owner, tokenMint, program } = solanaWorkspace( bridgeInfo.bridgeAddress, bridgeInfo.token.tokenAddress ) @@ -534,10 +534,7 @@ export class BridgeService { success: true, } } - // const bridgeInfo = await bridgeInfoRepo.findOne({ - // bridgeAddress, - // chainId, - // }) + const confirmations = CONFIRMATIONS[chainId as ChainId] const newTransaction = transactionRepo.create({ userAddress, index: +index, @@ -556,7 +553,7 @@ export class BridgeService { fulfillFromChain: tx.fromChain.replace('evm.', ''), fulfillNonce: +tx.nonce.toString(), txBlock: tx.block.toString(), - confirmations: CONFIRMATIONS[chainId as ChainId], + confirmations, transactionDate: new Date(Number(tx.timestamp) * 1000), symbol: bridgeInfo.token.symbol, bridgeInfoId: bridgeInfo.id, diff --git a/backend-all/src/services/token.ts b/backend-all/src/services/token.ts index 677871b..be180a9 100644 --- a/backend-all/src/services/token.ts +++ b/backend-all/src/services/token.ts @@ -8,7 +8,13 @@ import { providers, utils } from 'ethers' import { In } from 'typeorm' import { bridgeService } from '.' import { clusterApiUrl, Connection, PublicKey } from '@solana/web3.js' -import { getMint } from '@solana/spl-token' +import { + getAccount, + getAssociatedTokenAddress, + getMint, + TokenAccountNotFoundError, +} from '@solana/spl-token' +import { getSolanaConnection } from '@/utils/solana/helpers' export class TokenService { async addToken( @@ -47,10 +53,10 @@ export class TokenService { decimalsPromise, namePromise, ]) - if (symbol.toLowerCase() === 'xrwa'){ + if (symbol.toLowerCase() === 'xrwa') { symbol = 'RWA' } - if (symbol === "USD₮0" || symbol === "USDT0") symbol = "USDT"; + if (symbol === 'USD₮0' || symbol === 'USDT0') symbol = 'USDT' const newToken = await tokenRepo.create({ tokenAddress, chainId, @@ -168,6 +174,128 @@ export class TokenService { } } + async getTokenBalance( + evmAddress: string, + solanaAddess: string, + _tokens: { + chainId: ChainId + tokenAddress: string + bridgeAssist: string + checkAmountCanBridge: boolean + targetBlockTag: number, + symbol: string + }[] + ) { + const providers = new Map() + await Promise.all( + _tokens.map(async (token) => { + if (isSolChain(token.chainId)) { + return + } else { + providers.set(token.chainId, await _getProvider(token.chainId)) + } + }) + ) + const tokenBalances: any = {} + await Promise.all( + _tokens.map(async (token) => { + if (isSolChain(token.chainId)) { + if (!solanaAddess) return + const connection = getSolanaConnection(token.chainId) + const tokenBalancePromise = this.getSolanaTokenBalance( + solanaAddess, + token.tokenAddress, + connection + ) + const bridgeBalancePromise = this.getSolanaTokenBalance( + token.bridgeAssist, + token.tokenAddress, + connection + ) + const [tokenBalance, bridgeBalance] = await Promise.all([ + tokenBalancePromise, + bridgeBalancePromise, + ]) + if (!tokenBalances[token.chainId]) { + tokenBalances[token.chainId] = [] + } + const realUserTokenBalance = tokenBalance ? tokenBalance.amount.toString() : '0' + const realTBridgeBalance = bridgeBalance ? bridgeBalance.amount.toString() : '0' + tokenBalances[token.chainId].push({ + tokenAddress: token.tokenAddress, + userBalance: realUserTokenBalance, + bridgeBalance: realTBridgeBalance, + amountCanBridge: realUserTokenBalance, + symbol: token.symbol + }) + return + } else { + if (!evmAddress) return + if (!tokenBalances[token.chainId]) { + tokenBalances[token.chainId] = [] + } + if (token.tokenAddress === '0x0000000000000000000000000000000000000001') { + const provider = providers.get(token.chainId)! + const userBalancePromise = provider.getBalance(evmAddress) + const bridgeBalancePromise = provider.getBalance(token.bridgeAssist) + + const [userBalance, bridgeBalance] = await Promise.all([ + userBalancePromise, + bridgeBalancePromise, + ]) + + tokenBalances[token.chainId].push({ + tokenAddress: token.tokenAddress, + userBalance: userBalance.toString(), + bridgeBalance: bridgeBalance.toString(), + amountCanBridge: userBalance.toString(), + symbol: token.symbol + }) + return + } + const _token = anyToken(token.tokenAddress, providers.get(token.chainId)!) + const userBalancePromise = _token.balanceOf(evmAddress) + const bridgeBalancePromise = _token.balanceOf(token.bridgeAssist) + const [userBalance, bridgeBalance] = await Promise.all([ + userBalancePromise, + bridgeBalancePromise, + ]) + let amountCanBridge = userBalance + if (token.checkAmountCanBridge) { + amountCanBridge = await _token.balanceOf(evmAddress, { + blockTag: token.targetBlockTag, + }) + } + tokenBalances[token.chainId].push({ + tokenAddress: token.tokenAddress, + userBalance: userBalance.toString(), + bridgeBalance: bridgeBalance.toString(), + amountCanBridge: amountCanBridge.toString(), + symbol: token.symbol + }) + } + }) + ) + return tokenBalances + } + + async getTokenAllowance( + evmAddress: string, + spenderAddress: string, + token: { chainId: ChainId; tokenAddress: string } + ) { + const provider = await _getProvider(token.chainId) + const _token = anyToken(token.tokenAddress, provider) + const allowance = await _token.allowance(evmAddress, spenderAddress) + return { + tokenAddress: token.tokenAddress, + allowance: allowance.toString(), + chainId: token.chainId, + evmAddress, + spenderAddress, + } + } + async addSolanaToken(tokenAddress: string, chainId: ChainId, connection: Connection) { try { const mintPublicKey = new PublicKey(tokenAddress) @@ -187,4 +315,29 @@ export class TokenService { throw error } } + + async getSolanaTokenBalance( + ownerAddress: string, + mintAddress: string, + connection: Connection + ) { + const ownerPublicKey = new PublicKey(ownerAddress) + const mintPublicKey = new PublicKey(mintAddress) + + // Find the associated token account (ATA) + const ata = await getAssociatedTokenAddress(mintPublicKey, ownerPublicKey) + + try { + const accountInfo = await getAccount(connection, ata) + // console.log(accountInfo, "accountInfo"); + + return accountInfo + // console.log("Balance:", Number(accountInfo.amount) / Math.pow(10, accountInfo.decimals)); + } catch (err: any) { + if (err instanceof TokenAccountNotFoundError) { + return null + } + throw err + } + } } diff --git a/backend-all/src/types/index.ts b/backend-all/src/types/index.ts index 669a0d0..7c0bae6 100644 --- a/backend-all/src/types/index.ts +++ b/backend-all/src/types/index.ts @@ -1,5 +1,6 @@ import { BigNumber, BigNumberish } from 'ethers' import { useContracts } from '@/gotbit-tools/node' +import { ChainId } from '@/gotbit-tools/node/types' export interface AuthResponse { access_token: string token_type: string @@ -136,3 +137,23 @@ export interface MarkTransactionAsClaimedDto { claimTransactionHash: string toBridgeId: string } + +export interface GetTokenBalances { + tokens: { + tokenAddress: string + chainId: ChainId + bridgeAssist: string + checkAmountCanBridge: boolean + targetBlockTag: number, + symbol:string + }[] + evmAddress: string + solanaAddress: string +} + +export interface GetTokenAllowance { + evmAddress: string + spenderAddress: string + tokenAddress: string + chainId: ChainId +} diff --git a/backend-all/src/utils/solana/helpers.ts b/backend-all/src/utils/solana/helpers.ts index de308dc..8f5ff7b 100644 --- a/backend-all/src/utils/solana/helpers.ts +++ b/backend-all/src/utils/solana/helpers.ts @@ -513,3 +513,7 @@ export async function hasPassedConfirmationSolana( const block = await connection.getSlot() return BigNumber.from(block).gt(tx.block.add(getConfirmationsRequired(tx.fromChain))) } + +export function getSolanaConnection(chainId: string) { + return chainId === 'sol.mainnet' ? new Connection(clusterApiUrl('mainnet-beta'), 'confirmed') : new Connection(clusterApiUrl('devnet'), 'confirmed') +} From 7b30684349f9adb9865dd547243c4e7b234d23b9 Mon Sep 17 00:00:00 2001 From: Stephen Udeh <65906366+stephenson080@users.noreply.github.com> Date: Fri, 17 Oct 2025 16:19:20 +0100 Subject: [PATCH 18/19] bug Fix (#97) * worked on getting balance and block fromapi * bug fix with relayer --- backend-all/src/services/blockchain.ts | 69 +++++++++++++++----------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/backend-all/src/services/blockchain.ts b/backend-all/src/services/blockchain.ts index fdf70ca..5ed47c0 100644 --- a/backend-all/src/services/blockchain.ts +++ b/backend-all/src/services/blockchain.ts @@ -84,16 +84,15 @@ export const signTransaction = async ( let relayers = 1 // if (!fromChain.startsWith('evm.')) throw Error(`Relayer ${relayerIndex} Bad arguments`) if (process.env.IS_PUBLIC_RELAYER === 'true') { - const dbTransaction = await transactionRepo.findOne({ id: transactionId }) - if (!dbTransaction) throw Error('Transaction not found') + const dbTransaction = await transactionRepo.findOne({ id: transactionId }) + if (!dbTransaction) throw Error('Transaction not found') } const _fromChain = fromChain.replace('evm.', '') as ChainId const _provider = await _getProvider(_fromChain) const contract = anyBridgeAssist(fromBridgeAddress, _provider) const transactionPromise = contract.transactions(fromUser, index) - const relayerLengthPromise = contract.relayersLength() - const res = await Promise.all([transactionPromise, relayerLengthPromise]) - tx = res[0] + // const relayerLengthPromise = contract.relayersLength() + tx = await transactionPromise if (!tx || tx.block.toNumber() === 0) throw Error('Transaction not found') if ( _fromChain === '42161' || @@ -101,8 +100,6 @@ export const signTransaction = async ( ) await checkToken(fromUser, contract, _fromChain, tx) - relayers = +res[1].toNumber() - // const provider = getProvider(fromChain.slice(4) as ChainId) const currentBlock = await safeRead(_provider.getBlockNumber(), 0) if (currentBlock === 0 || tx.block.gt(currentBlock)) @@ -110,7 +107,11 @@ export const signTransaction = async ( if (!tx.toChain.startsWith('evm.')) throw Error(`Relayer ${relayerIndex} bad contract params`) - const { isFulfilled } = await fulfilledInfo(tx, toBridgeAddress) + + const chainId = tx.toChain.replace('evm.', '') + const toProvider = await _getProvider(chainId as ChainId) + const toBridgeAddressContract = anyBridgeAssist(toBridgeAddress, toProvider) + const { isFulfilled } = await fulfilledInfo(toBridgeAddressContract, tx) if (isFulfilled) { if (process.env.IS_PUBLIC_RELAYER === 'true') { await transactionRepo.update(transactionId, { fulfilled: true }) @@ -118,9 +119,9 @@ export const signTransaction = async ( throw new Error('Token has already claimed') } - // if (tx.toChain.startsWith('evm.')) { - const chainId = tx.toChain.replace('evm.', '') - // const { bridgeAssist } = useContracts(undefined, chainId as ChainId) + const relayersLength = await toBridgeAddressContract.relayersLength() + relayers = relayersLength.toNumber() + let signatures: string[] = [] const allowedIps = process.env.ALLOWED_IPS?.split(',') const clientIp = getClientIp(req) @@ -342,9 +343,10 @@ async function checkWNTRestriction( if (+transaction.timestamp.toString() < timeStamp) return const toChain = transaction.toChain.replace('evm.', '') const toBridgeAddress = (chainBridgeAssit as any)[toChain] - console.log(toBridgeAddress, 'toBridgeAddress') if (!toBridgeAddress) throw new Error(`Failed to get to bridge Assist address`) - const { isFulfilled } = await fulfilledInfo(transaction, toBridgeAddress) + const toProvider = await _getProvider(toChain as ChainId) + const toBridgeAddressContract = anyBridgeAssist(toBridgeAddress, toProvider) + const { isFulfilled } = await fulfilledInfo(toBridgeAddressContract, transaction) if (!isFulfilled) return const amount = +utils.formatUnits(transaction.amount, 18) totalBridged += amount @@ -364,11 +366,18 @@ async function checkWNTRestriction( } } -async function fulfilledInfo(tx: TransactionContract, bridgeAddress: string) { - const toChain = tx.toChain.replace('evm.', '') as ChainId - const provider = await _getProvider(toChain) - const bridgeAssist = anyBridgeAssist(bridgeAddress, provider) - const fulfilledAt = await bridgeAssist.fulfilledAt(tx.fromChain, tx.fromUser, tx.nonce) +async function fulfilledInfo( + toBridgeAddressContract: BridgeAssist, + tx: TransactionContract +) { + // const toChain = tx.toChain.replace('evm.', '') as ChainId + // const provider = await _getProvider(toChain) + // const bridgeAssist = anyBridgeAssist(bridgeAddress, provider) + const fulfilledAt = await toBridgeAddressContract.fulfilledAt( + tx.fromChain, + tx.fromUser, + tx.nonce + ) return { isFulfilled: Number(fulfilledAt) > 0, @@ -379,18 +388,20 @@ async function fulfilledInfo(tx: TransactionContract, bridgeAddress: string) { // get block number by chainId, param is list of chainIds should be in promise.all export const getBlockNumber = async (chainIds: ChainId[]) => { - const blockNumbers : any= {} - await Promise.all(chainIds.map(async (chainId) => { - if (isSolChain(chainId)) { - const connection = getSolanaConnection(chainId) - const blockNumber = await connection.getSlot() + const blockNumbers: any = {} + await Promise.all( + chainIds.map(async (chainId) => { + if (isSolChain(chainId)) { + const connection = getSolanaConnection(chainId) + const blockNumber = await connection.getSlot() + blockNumbers[chainId] = +blockNumber.toString() + return + } + const provider = await _getProvider(chainId) + const blockNumber = await provider.getBlockNumber() blockNumbers[chainId] = +blockNumber.toString() - return - } - const provider = await _getProvider(chainId) - const blockNumber = await provider.getBlockNumber() - blockNumbers[chainId] = +blockNumber.toString() - })) + }) + ) return blockNumbers } From 9e50923ce186d500ac8ce54f6a641260acf098cb Mon Sep 17 00:00:00 2001 From: Stephen Udeh Date: Sat, 18 Oct 2025 00:09:38 +0100 Subject: [PATCH 19/19] bug fix --- backend-all/src/services/token.ts | 42 +++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/backend-all/src/services/token.ts b/backend-all/src/services/token.ts index be180a9..5cb0e1e 100644 --- a/backend-all/src/services/token.ts +++ b/backend-all/src/services/token.ts @@ -14,7 +14,7 @@ import { getMint, TokenAccountNotFoundError, } from '@solana/spl-token' -import { getSolanaConnection } from '@/utils/solana/helpers' +import { getSolanaConnection, SOL_CHAIN_BUFFER, SOLANA_PROGRAM_VERSION, solanaWorkspace } from '@/utils/solana/helpers' export class TokenService { async addToken( @@ -197,6 +197,7 @@ export class TokenService { }) ) const tokenBalances: any = {} + await Promise.all( _tokens.map(async (token) => { if (isSolChain(token.chainId)) { @@ -207,7 +208,8 @@ export class TokenService { token.tokenAddress, connection ) - const bridgeBalancePromise = this.getSolanaTokenBalance( + + const bridgeBalancePromise = this.getBridgeTokenBalance( token.bridgeAssist, token.tokenAddress, connection @@ -340,4 +342,40 @@ export class TokenService { throw err } } + + async getBridgeTokenBalance( + bridgeAddress: string, + mintAddress: string, + connection: Connection + ) { + const tokenMint = new PublicKey(mintAddress); + const {owner} = solanaWorkspace(bridgeAddress, mintAddress) + const programId = new PublicKey(bridgeAddress) + + const [bridgeTokenPda] = PublicKey.findProgramAddressSync( + [ + SOLANA_PROGRAM_VERSION().toBuffer('be', 8), + Buffer.from("wallet"), + owner.publicKey.toBuffer(), + tokenMint.toBuffer(), + SOL_CHAIN_BUFFER(), + ], + programId + ); + + // Find the associated token account (ATA) + + try { + const accountInfo = await getAccount(connection, bridgeTokenPda); + // console.log(accountInfo, "accountInfo"); + + return accountInfo + // console.log("Balance:", Number(accountInfo.amount) / Math.pow(10, accountInfo.decimals)); + } catch (err: any) { + if (err instanceof TokenAccountNotFoundError) { + return null + } + throw err; + } + } }