mirror of
https://github.com/luxfi/bridge.git
synced 2026-09-24 00:26:46 +00:00
update: mpc nodes
This commit is contained in:
@@ -119,7 +119,23 @@ export const sourceNetworks: Network[] = [
|
||||
destination_base_fee: 0.99,
|
||||
is_native: false
|
||||
},
|
||||
|
||||
{
|
||||
name: "DAI",
|
||||
asset: "DAI",
|
||||
logo: "https://cdn.lux.network/bridge/currencies/dai.png",
|
||||
contract_address: "0x7390C3FA8576a0E9E7c788cc7955c3151c4c1612",
|
||||
decimals: 18,
|
||||
status: "active",
|
||||
is_deposit_enabled: true,
|
||||
is_withdrawal_enabled: true,
|
||||
is_refuel_enabled: true,
|
||||
max_withdrawal_amount: 3000,
|
||||
deposit_fee: 12.79,
|
||||
withdrawal_fee: 6.4,
|
||||
source_base_fee: 0.99,
|
||||
destination_base_fee: 0.99,
|
||||
is_native: false
|
||||
},
|
||||
{
|
||||
name: "LRC",
|
||||
asset: "LRC",
|
||||
@@ -379,7 +395,6 @@ export const sourceNetworks: Network[] = [
|
||||
node: "https://eth-mainnet.g.alchemy.com/v2/-z4Zrujiou9ajXAplVapFFWWrPuLPSm7",
|
||||
currencies: []
|
||||
},
|
||||
|
||||
]
|
||||
|
||||
export const sourceNetworks_: Network[] = [
|
||||
@@ -502,7 +517,23 @@ export const sourceNetworks_: Network[] = [
|
||||
destination_base_fee: 0.99,
|
||||
is_native: false
|
||||
},
|
||||
|
||||
{
|
||||
name: "DAI",
|
||||
asset: "DAI",
|
||||
logo: "https://cdn.lux.network/bridge/currencies/dai.png",
|
||||
contract_address: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
||||
decimals: 18,
|
||||
status: "active",
|
||||
is_deposit_enabled: true,
|
||||
is_withdrawal_enabled: true,
|
||||
is_refuel_enabled: true,
|
||||
max_withdrawal_amount: 3000,
|
||||
deposit_fee: 12.79,
|
||||
withdrawal_fee: 6.4,
|
||||
source_base_fee: 0.99,
|
||||
destination_base_fee: 0.99,
|
||||
is_native: false
|
||||
},
|
||||
{
|
||||
name: "LRC",
|
||||
asset: "LRC",
|
||||
|
||||
@@ -15,17 +15,9 @@ pragma solidity ^0.8.19;
|
||||
|
||||
import "./ERC20B.sol";
|
||||
|
||||
contract LuxETH is ERC20B {
|
||||
contract LETH is ERC20B {
|
||||
string public constant _name = "Lux ETH";
|
||||
string public constant _symbol = "LETH";
|
||||
|
||||
constructor() ERC20B(_name, _symbol) {}
|
||||
|
||||
function mint(address account, uint256 amount) public {
|
||||
_mint(account, amount);
|
||||
}
|
||||
|
||||
function burn(address account, uint256 amount) public {
|
||||
_burn(account, amount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,15 +16,5 @@ contract LUSD is ERC20B {
|
||||
string public constant _name = "Lux Dollar";
|
||||
string public constant _symbol = "LUSD";
|
||||
|
||||
constructor() ERC20B(_name, _symbol) {
|
||||
_mint(msg.sender, 10000000000 * 10 ** decimals());
|
||||
}
|
||||
|
||||
function mint(address account, uint256 amount) public {
|
||||
_mint(account, amount);
|
||||
}
|
||||
|
||||
function burn(address account, uint256 amount) public {
|
||||
_burn(account, amount);
|
||||
}
|
||||
constructor() ERC20B(_name, _symbol) {}
|
||||
}
|
||||
|
||||
@@ -9,30 +9,45 @@ const PRIVATE_KEY: string = process.env.PRIVATE_KEY!;
|
||||
const SEPOLIA_RPC: string = process.env.SEPOLIA_RPC!;
|
||||
const BASE_RPC: string = process.env.BASE_RPC!;
|
||||
const BSC_TESTNET_RPC: string = process.env.BSC_TESTNET_RPC!;
|
||||
const LUX_MAINNET_RPC: string = process.env.LUX_MAINNET_RPC!;
|
||||
|
||||
const config: HardhatUserConfig = {
|
||||
solidity: "0.8.20",
|
||||
// defaultNetwork: "sepolia",
|
||||
networks: {
|
||||
sepolia: {
|
||||
url: SEPOLIA_RPC,
|
||||
accounts: [PRIVATE_KEY],
|
||||
accounts: [`0x${PRIVATE_KEY}`],
|
||||
},
|
||||
bsc_testnet: {
|
||||
url: BSC_TESTNET_RPC,
|
||||
accounts: [PRIVATE_KEY]
|
||||
accounts: [`0x${PRIVATE_KEY}`],
|
||||
},
|
||||
base: {
|
||||
url: BASE_RPC,
|
||||
accounts: [PRIVATE_KEY]
|
||||
}
|
||||
accounts: [`0x${PRIVATE_KEY}`],
|
||||
},
|
||||
lux: {
|
||||
url: LUX_MAINNET_RPC,
|
||||
accounts: [`0x${PRIVATE_KEY}`],
|
||||
},
|
||||
},
|
||||
etherscan: {
|
||||
apiKey: {
|
||||
sepolia: process.env.ETHERSCAN_API_KEY!,
|
||||
bsc: process.env.BSCSCAN_API_KEY!,
|
||||
bscTestnet: process.env.BSCSCAN_API_KEY!
|
||||
}
|
||||
bscTestnet: process.env.BSCSCAN_API_KEY!,
|
||||
lux: "your API key" // Leave empty if not applicable
|
||||
},
|
||||
customChains: [
|
||||
{
|
||||
network: "lux",
|
||||
chainId: 7777,
|
||||
urls: {
|
||||
apiURL: "https://api.lux.network",
|
||||
browserURL: "https://explore.lux.network"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
sourcify: {
|
||||
enabled: true,
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"@types/node": ">=18.0.0",
|
||||
"chai": "^4.2.0",
|
||||
"ethers": "^6.4.0",
|
||||
"hardhat": "^2.22.8",
|
||||
"hardhat": "^2.22.9",
|
||||
"hardhat-gas-reporter": "^1.0.8",
|
||||
"solidity-coverage": "^0.8.0",
|
||||
"ts-node": ">=8.0.0",
|
||||
@@ -23,6 +23,7 @@
|
||||
"typescript": ">=4.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nomiclabs/hardhat-etherscan": "^3.1.8",
|
||||
"@openzeppelin/contracts": "^5.0.2",
|
||||
"dotenv": "^16.4.5"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { ethers } from "hardhat";
|
||||
|
||||
async function main() {
|
||||
const [deployer] = await ethers.getSigners();
|
||||
|
||||
/////LETH
|
||||
const _signer = await ethers.getContractFactory("LETH");
|
||||
const token = await _signer.deploy();
|
||||
console.log("LETH address:", await token.getAddress());
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
import { ethers } from "hardhat";
|
||||
|
||||
async function main() {
|
||||
const [deployer] = await ethers.getSigners();
|
||||
|
||||
/////LETH
|
||||
const _signer = await ethers.getContractFactory("LUSD");
|
||||
const token = await _signer.deploy();
|
||||
console.log("LUSD address:", await token.getAddress());
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,5 +1,15 @@
|
||||
smTimeOutBound=20
|
||||
sign_client_name="gg18_sign_client"
|
||||
node_number=0
|
||||
sign_sm_manager="http://127.0.0.1:8000"
|
||||
PORT=6000
|
||||
smTimeOutBound=
|
||||
sign_client_name=
|
||||
node_number=
|
||||
sign_sm_manager=
|
||||
PORT=
|
||||
|
||||
# This was inserted by `prisma init`:
|
||||
# Environment variables declared in this file are automatically made available to Prisma.
|
||||
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema
|
||||
|
||||
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
|
||||
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
|
||||
|
||||
POSTGRES_PRISMA_URL=
|
||||
POSTGRES_URL_NON_POOLING=
|
||||
@@ -36,6 +36,7 @@
|
||||
"typescript": "^5.5.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@prisma/client": "^5.19.1",
|
||||
"axios": "^1.7.4",
|
||||
"child_process": "^1.0.2",
|
||||
"cors": "^2.8.5",
|
||||
@@ -43,6 +44,7 @@
|
||||
"ethers": "^6.13.2",
|
||||
"express": "^4.19.2",
|
||||
"find-process": "^1.4.7",
|
||||
"prisma": "^5.19.1",
|
||||
"web3": "^4.11.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,20 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "Teleporter" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"txId" TEXT NOT NULL,
|
||||
"chainType" TEXT NOT NULL,
|
||||
"amount" TEXT NOT NULL,
|
||||
"signature" TEXT NOT NULL,
|
||||
"hashedTxId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "Teleporter_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Teleporter_txId_key" ON "Teleporter"("txId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Teleporter_signature_key" ON "Teleporter"("signature");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Teleporter_hashedTxId_key" ON "Teleporter"("hashedTxId");
|
||||
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
provider = "postgresql"
|
||||
@@ -0,0 +1,35 @@
|
||||
// This is your Prisma schema file,
|
||||
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||
|
||||
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
|
||||
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("POSTGRES_PRISMA_URL") // uses connection pooling
|
||||
directUrl = env("POSTGRES_URL_NON_POOLING") // uses a direct connection
|
||||
}
|
||||
|
||||
// datasource db {
|
||||
// provider = "sqlite"
|
||||
// url = "file:dev.sqlite?socket_timeout=50000" // uses connection pooling
|
||||
// directUrl = "file:dev.sqlite?socket_timeout=50000" // uses a direct connection
|
||||
// }
|
||||
|
||||
// pnpx prisma generate
|
||||
// npx prisma db push
|
||||
// npx prisma studio
|
||||
// prisma migrate dev
|
||||
|
||||
model Teleporter {
|
||||
id Int @id @default(autoincrement())
|
||||
txId String @unique
|
||||
chainType String
|
||||
amount String
|
||||
signature String @unique
|
||||
hashedTxId String @unique
|
||||
}
|
||||
@@ -1,36 +1,62 @@
|
||||
export const settings = {
|
||||
Vault: "0x568BF299E115D78a1fBa57BafdAe0fD8A26BFb7e",
|
||||
RPC: {
|
||||
11155111: "https://sepolia.infura.io/v3/2e58a899d3c64eccb6955c2f33fc8a88",
|
||||
97: "https://data-seed-prebsc-1-s1.bnbchain.org:8545"
|
||||
1: "https://lb.drpc.org/ogrpc?network=ethereum&dkey=AqFR4xsp40v0ugTBeYcYdFLf2rXfQTYR76p2UgWAgP__",
|
||||
7777: "https://api.lux.network"
|
||||
},
|
||||
LuxETH: {
|
||||
Ethereum: "0x42449554b0c7D85EbD488e14D7D48c6A78D3F9Be",
|
||||
Lux: "0x41e51eFcdA08fDFB84f4b1caa4b7f03c67FA431b"
|
||||
},
|
||||
LuxBTC: {
|
||||
Ethereum: "0x526903Ee6118de6737D11b37f82fC7f69B13685D",
|
||||
Lux: "0x8c07F93A76213c0BE738ded6110403b6d0ceE286"
|
||||
},
|
||||
// WSHM: {
|
||||
// "Ethereum": "0xc1Dd1e835F4cdFF9fc12Cb1750428E345A3d3d5f",
|
||||
// "Lux": "0x2d6Bce32Ea63F2e2CDfCAd49999e89a00389Df4C",
|
||||
// },
|
||||
Teleporter: {
|
||||
Ethereum: "0x5519582dde6eb1f53F92298622c2ecb39A64369A",
|
||||
LETH: {
|
||||
Ethereum: "",
|
||||
Sepolia: "",
|
||||
Lux: "0x42449554b0c7D85EbD488e14D7D48c6A78D3F9Be"
|
||||
},
|
||||
LUSD: {
|
||||
Ethereum: "",
|
||||
Sepolia: "",
|
||||
Lux: "0xc16ECFE3cB80e142d7110b97a442d4caAA203ABf"
|
||||
},
|
||||
Teleporter: {
|
||||
Ethereum: "",
|
||||
Sepolia: "0x568BF299E115D78a1fBa57BafdAe0fD8A26BFb7e",
|
||||
Lux: "0xB2237fb7DBB19Ff09BBD64029064eC05B3C369Ac"
|
||||
},
|
||||
USDT: {
|
||||
Ethereum: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
Sepolia: "0xa92e09451140d645a2fe262c9631dd808439dded"
|
||||
},
|
||||
USDC: {
|
||||
Ethereum: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
||||
Sepolia: "0xB587bAb3d507d720625D30544C2889D661446BF7"
|
||||
},
|
||||
DAI: {
|
||||
Ethereum: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
||||
Sepolia: "0x7390C3FA8576a0E9E7c788cc7955c3151c4c1612"
|
||||
},
|
||||
ETH: {
|
||||
Ethereum: "0x0000000000000000000000000000000000000000",
|
||||
Sepolia: "0x0000000000000000000000000000000000000000"
|
||||
},
|
||||
NetNames: {
|
||||
"11155111": "Ethereum",
|
||||
"97": "Lux"
|
||||
"11155111": "Sepolia",
|
||||
"1": "Ethereum",
|
||||
"7777": "Lux"
|
||||
},
|
||||
DECIMALS: {
|
||||
ETH: "18",
|
||||
USDT: "6",
|
||||
USDC: "6",
|
||||
DAI: "18"
|
||||
},
|
||||
Msg: "Sign to prove you are initiator of transaction.",
|
||||
DupeListLimit: "200",
|
||||
SMTimeout: "1",
|
||||
NewSigAllowed: false,
|
||||
SigningManagers: ["http://127.0.0.1:8000", "http://127.0.0.1:8000"],
|
||||
MPCPeers: {
|
||||
0: "mnode.wpkt.cash, 139.162.85.205",
|
||||
1: "mnode.odapp.io, 172.104.108.56"
|
||||
},
|
||||
KeyStore: "keys.store"
|
||||
}
|
||||
|
||||
export const swapMappings: Record<string, string[] | undefined> = {
|
||||
// LETH swap available tokens (native ETH or wrapped ETH)
|
||||
"0xa684c5721e54B871111CE1F1E206d669a7e7F0a5": ["ETH", "WETH"],
|
||||
// LUSD swap available tokens (stable coins)
|
||||
"0xa684c5721e54B871111CE1F1E206d669a7e7F0a6": ["USDT", "USDC", "DAI", "BUSD", "TUSD", "USDP", "HUSD", "SUSD", "USDN"]
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
{
|
||||
"RPC": {
|
||||
"11155111": "https://sepolia.infura.io/v3/2e58a899d3c64eccb6955c2f33fc8a88",
|
||||
"97": "https://data-seed-prebsc-1-s1.bnbchain.org:8545"
|
||||
},
|
||||
"LuxETH": {
|
||||
"Ethereum": "0x42449554b0c7D85EbD488e14D7D48c6A78D3F9Be",
|
||||
"Lux": "0xFa005D52398B4BdAAf73C4e2E3AF8095533D790E"
|
||||
},
|
||||
"LuxBTC": {
|
||||
"Ethereum": "0x526903Ee6118de6737D11b37f82fC7f69B13685D",
|
||||
"Lux": "0x8c07F93A76213c0BE738ded6110403b6d0ceE286"
|
||||
},
|
||||
// "WSHM": {
|
||||
// "Ethereum": "0xc1Dd1e835F4cdFF9fc12Cb1750428E345A3d3d5f",
|
||||
// "Lux": "0x2d6Bce32Ea63F2e2CDfCAd49999e89a00389Df4C",
|
||||
// },
|
||||
"Teleporter": {
|
||||
"Ethereum": "0x5519582dde6eb1f53F92298622c2ecb39A64369A",
|
||||
"Lux": "0x42449554b0c7D85EbD488e14D7D48c6A78D3F9Be"
|
||||
},
|
||||
"NetNames": {
|
||||
"11155111": "Ethereum",
|
||||
"97": "Lux"
|
||||
},
|
||||
"DB": "<change to somePassthatisSUperDuperPrivate123AbcBlahBlahBlah>",
|
||||
"Msg": "Sign to prove you are initiator of transaction.",
|
||||
"DupeListLimit": "200",
|
||||
"SMTimeout": "1",
|
||||
"NewSigAllowed": false,
|
||||
"SigningManagers": {
|
||||
"0": "http://mpc.wpkt.cash",
|
||||
"1": "http://mpc.odapp.io"
|
||||
},
|
||||
"MPCPeers": {
|
||||
"0": "mnode.wpkt.cash, 139.162.85.205",
|
||||
"1": "mnode.odapp.io, 172.104.108.56"
|
||||
},
|
||||
"KeyStore": {
|
||||
"0": "keys2.store"
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,14 @@ import Web3 from "web3"
|
||||
import { Interface } from "ethers"
|
||||
import { promisify } from "util"
|
||||
import { exec as childExec } from "child_process"
|
||||
import { settings } from "./config"
|
||||
import { settings, swapMappings } from "./config"
|
||||
import { RegisteredSubscription } from "web3/lib/commonjs/eth.exports"
|
||||
import { hashAndSignTx, signClient, sleep } from "./utils"
|
||||
import { PrismaClient } from "@prisma/client"
|
||||
|
||||
const exec = promisify(childExec)
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
/* Settings Mapping */
|
||||
const settingsMap = new Map()
|
||||
|
||||
@@ -30,6 +33,8 @@ for (const [key, value] of Object.entries(settings)) {
|
||||
const rpcList = settings.RPC
|
||||
/* Networks (ie. chains) */
|
||||
const networkName = settings.NetNames
|
||||
/* DECIMAL LIST */
|
||||
const DECIMALS = settings.DECIMALS
|
||||
/* Signature Re-signing flag */
|
||||
const newSigAllowed = settings.NewSigAllowed
|
||||
/* Signing MSG */
|
||||
@@ -41,15 +46,39 @@ let dupeList = new Map()
|
||||
/* Bridge contracts for Teleport Bridge */
|
||||
const list = settings.Teleporter
|
||||
|
||||
function getWeb3ForId(toNetId: number) {
|
||||
return new Web3(new Web3.providers.HttpProvider(rpcList[toNetId]))
|
||||
/**
|
||||
* get WEB3 object by given network id
|
||||
* @param networkId
|
||||
* @returns
|
||||
*/
|
||||
function getWeb3ForId(networkId: number) {
|
||||
try {
|
||||
const _web3 = new Web3(new Web3.providers.HttpProvider(rpcList[networkId]))
|
||||
return Promise.resolve(_web3)
|
||||
} catch (err) {
|
||||
return Promise.reject("error to build web3 object")
|
||||
}
|
||||
}
|
||||
|
||||
/* Given network id returns the appropriate contract to talk to as array of values */
|
||||
const getNetworkAddresses = (toNetId: number, tokenName: string) => {
|
||||
const web3 = getWeb3ForId(toNetId)
|
||||
const chainName: string = networkName[toNetId]
|
||||
return [settingsMap.get(tokenName.toString())[chainName], web3, list[chainName]]
|
||||
/**
|
||||
* Given network id returns the appropriate contract to talk to as array of values
|
||||
* @param networkId
|
||||
* @param tokenName
|
||||
* @returns boject { fromTokenConAddr, w3From, frombridgeConAddr }
|
||||
*/
|
||||
const getNetworkInfo = async (networkId: number, tokenName: string) => {
|
||||
try {
|
||||
const web3 = await getWeb3ForId(networkId)
|
||||
const chainName: string = networkName[networkId]
|
||||
if (!chainName) throw "no chain"
|
||||
return {
|
||||
fromTokenConAddr: settingsMap.get(tokenName.toString())[chainName],
|
||||
w3From: web3,
|
||||
frombridgeConAddr: list[chainName]
|
||||
}
|
||||
} catch (err) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const Exp = /((^[0-9]+[a-z]+)|(^[a-z]+[0-9]+))+[0-9a-z]+$/i
|
||||
@@ -72,233 +101,379 @@ app.get("/", async (req: express.Request, res: express.Response) => {
|
||||
* Parameters specific to where funds are being moved / minted to, are hashed, such that only the user has knowledge of
|
||||
* mint destination. Effectively, the transaction is teleported stealthily.
|
||||
*/
|
||||
app.get(
|
||||
"/api/v1/getsig/txid/:txid/fromNetId/:fromNetId/toNetIdHash/:toNetIdHash/tokenName/:tokenName/tokenAddrHash/:tokenAddrHash/msgSig/:msgSig/toTargetAddrHash/:toTargetAddrHash/nonce/:nonce",
|
||||
async (req: express.Request, res: express.Response) => {
|
||||
// Checking inputs
|
||||
const stealthMode = true // Stealth overrride by default, for now.
|
||||
let sig: string = ""
|
||||
let evmTxHash: string = ""
|
||||
let output: any = null
|
||||
app.get("/api/v1/getsig/txid/:txid/fromNetId/:fromNetId/toNetIdHash/:toNetIdHash/tokenName/:tokenName/tokenAddr/:tokenAddr/msgSig/:msgSig/toTargetAddrHash/:toTargetAddrHash/nonce/:nonce", async (req: express.Request, res: express.Response) => {
|
||||
// Checking inputs
|
||||
const stealthMode = true // Stealth overrride by default, for now.
|
||||
|
||||
const txid = req.params.txid.trim()
|
||||
if (!(txid.length > 0) && !txid.match(Exp)) {
|
||||
output = "NullTransactionError: bad transaction hash"
|
||||
return res.send(output)
|
||||
const txid = req.params.txid.trim()
|
||||
if (!(txid.length > 0) && !txid.match(Exp)) {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "NullTransactionError: bad transaction hash"
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
|
||||
// Dupelist reset if time has elapsed.
|
||||
const dupeStop = new Date() //time now
|
||||
if ((Number(dupeStop) - dupeStart) / 1000 >= 2400) {
|
||||
dupeList = new Map() //Clear dupeList
|
||||
dupeStart = new Date().getTime()
|
||||
}
|
||||
// Dupelist reset if time has elapsed.
|
||||
const dupeStop = new Date() //time now
|
||||
if ((Number(dupeStop) - dupeStart) / 1000 >= 2400) {
|
||||
dupeList = new Map() //Clear dupeList
|
||||
dupeStart = new Date().getTime()
|
||||
}
|
||||
|
||||
// Limit on checks here, else you go into graylist.
|
||||
if (dupeList.get(txid.toString()) == undefined) {
|
||||
//First time
|
||||
dupeList.set(txid.toString(), 0) // init
|
||||
} else {
|
||||
if (dupeList.get(txid.toString()) >= dupeListLimit) {
|
||||
// temp blacklist - pm2 cron will reset graylist after 12hrs
|
||||
console.log("Dupe transaction request limit hit")
|
||||
output = "DupeTransactionError: Too many transaction requests. Try back later."
|
||||
res.send(output)
|
||||
return
|
||||
// Limit on checks here, else you go into graylist.
|
||||
if (dupeList.get(txid.toString()) == undefined) {
|
||||
//First time
|
||||
dupeList.set(txid.toString(), 0) // init
|
||||
} else {
|
||||
if (dupeList.get(txid.toString()) >= dupeListLimit) {
|
||||
// temp blacklist - pm2 cron will reset graylist after 12hrs
|
||||
console.log("Dupe transaction request limit hit")
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "DupeTransactionError: Too many transaction requests. Try back later."
|
||||
}
|
||||
dupeList.set(txid.toString(), dupeList.get(txid.toString()) + 1)
|
||||
}
|
||||
|
||||
const fromNetId = req.params.fromNetId.trim()
|
||||
console.log("fromNetId:", fromNetId)
|
||||
if (!fromNetId) {
|
||||
output = "NullFromNetIDError: No from netId sent."
|
||||
res.send(output)
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
dupeList.set(txid.toString(), dupeList.get(txid.toString()) + 1)
|
||||
}
|
||||
|
||||
const toNetIdHash = req.params.toNetIdHash.trim()
|
||||
if (!toNetIdHash) {
|
||||
output = "NullToNetIDHashError: No to netId sent."
|
||||
res.send(output)
|
||||
return
|
||||
const fromNetId = req.params.fromNetId.trim()
|
||||
if (!fromNetId) {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "NullFromNetIDError: No from netId sent."
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
|
||||
const tokenName = req.params.tokenName.trim()
|
||||
if (!tokenName) {
|
||||
output = "NullTokenNameError: No token name sent."
|
||||
res.send(output)
|
||||
return
|
||||
const toNetIdHash = req.params.toNetIdHash.trim()
|
||||
if (!toNetIdHash) {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "NullToNetIDHashError: No to netId sent."
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
|
||||
const tokenAddrHash = req.params.tokenAddrHash.trim()
|
||||
console.log("TokenAddrHash:", tokenAddrHash)
|
||||
if (!tokenAddrHash) {
|
||||
output = "NullTokenAddressHashError: No token address hash sent."
|
||||
res.send(output)
|
||||
return
|
||||
const tokenName = req.params.tokenName.trim()
|
||||
if (!tokenName) {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "NullTokenNameError: No token name sent."
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
|
||||
let toTargetAddrHash = req.params.toTargetAddrHash.trim()
|
||||
if (!toTargetAddrHash) {
|
||||
output = "NullToTargetAddrHashError: No target address hash sent."
|
||||
res.send(output)
|
||||
return
|
||||
const tokenAddr = req.params.tokenAddr.trim()
|
||||
if (!tokenAddr) {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "NullTokenAddressHashError: No token address sent."
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
|
||||
const msgSig = req.params.msgSig.trim()
|
||||
if (!msgSig) {
|
||||
output = "NullMessageSignatureError: Challenge message signature not sent."
|
||||
res.send(output)
|
||||
return
|
||||
let toTargetAddrHash = req.params.toTargetAddrHash.trim()
|
||||
if (!toTargetAddrHash) {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "NullToTargetAddrHashError: No target address hash sent."
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
|
||||
const nonce = req.params.nonce.trim()
|
||||
if (!nonce) {
|
||||
output = "NullNonceError: No nonce sent."
|
||||
res.send(output)
|
||||
return
|
||||
const msgSig = req.params.msgSig.trim()
|
||||
if (!msgSig) {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "NullMessageSignatureError: Challenge message signature not sent."
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
|
||||
const fromNetArr = getNetworkAddresses(Number(fromNetId), tokenName)
|
||||
// console.log("fromNetArr:", fromNetArr)
|
||||
evmTxHash = Web3.utils.soliditySha3(txid)
|
||||
const txidNonce = stealthMode ? evmTxHash + nonce : txid + nonce
|
||||
const txStub = stealthMode ? evmTxHash : txid
|
||||
const txInfo = [txStub, fromNetId, toNetIdHash, tokenName, tokenAddrHash, toTargetAddrHash, msgSig, nonce]
|
||||
// console.log("txidNonce:", txidNonce)
|
||||
// console.log("txProcMapX:", txProcMap.get(txidNonce.toString()), "TX MAP:", txProcMap)
|
||||
|
||||
if (fromNetArr.length !== 3) {
|
||||
console.log("FromNetArrLengthError:", fromNetArr.length)
|
||||
output = "Unknown error occurred."
|
||||
res.send(output)
|
||||
return
|
||||
const nonce = req.params.nonce.trim()
|
||||
if (!nonce) {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "NullNonceError: No nonce sent."
|
||||
}
|
||||
const fromTokenConAddr: string = fromNetArr[0]
|
||||
const frombridgeConAddr: string = fromNetArr[2]
|
||||
const w3From: Web3<RegisteredSubscription> = fromNetArr[1]
|
||||
const cnt = 0
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
// TODO: check swap available according to source tokenName and destination token address
|
||||
const _availableTokensByDesTokenAddress = swapMappings[tokenAddr]
|
||||
if (!_availableTokensByDesTokenAddress) {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "NullDestinationTokenError: No destination Token."
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
if (!_availableTokensByDesTokenAddress.includes(tokenName)) {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "NullDestinationTokenError: No Swap Permitted Token."
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
|
||||
const transaction = await getEVMTx(txid, w3From)
|
||||
if (!transaction) {
|
||||
output = { error: "NullTransactionError: bad transaction hash, no transaction on chain" }
|
||||
res.send(output)
|
||||
const tokenAddrHash = Web3.utils.keccak256(tokenAddr) // hash the destinationTokenAddress
|
||||
const evmTxHash = Web3.utils.soliditySha3(txid)
|
||||
|
||||
// check replay attack
|
||||
const { status, data } = await checkStealthSignature(evmTxHash)
|
||||
if (status) {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "DuplicatedTxHashError: TxHash already exists."
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
|
||||
const txidNonce = stealthMode ? evmTxHash + nonce : txid + nonce
|
||||
const txStub = stealthMode ? evmTxHash : txid
|
||||
const txInfo = [txStub, fromNetId, toNetIdHash, tokenName, tokenAddrHash, toTargetAddrHash, msgSig, nonce]
|
||||
// console.log("txidNonce:", txidNonce)
|
||||
// console.log("txProcMapX:", txProcMap.get(txidNonce.toString()), "TX MAP:", txProcMap)
|
||||
// get network settings
|
||||
const fromNetArr = await getNetworkInfo(Number(fromNetId), tokenName)
|
||||
|
||||
if (!fromNetArr) {
|
||||
console.log("FromNetArrLengthError:")
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "Invalid source network settings."
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
|
||||
const { fromTokenConAddr, w3From, frombridgeConAddr } = fromNetArr
|
||||
// get transaction info according to chains
|
||||
const transaction = await getEVMTx(txid, w3From)
|
||||
if (!transaction) {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "NullTransactionError: bad transaction hash, no transaction on chain"
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
} else {
|
||||
const { teleporter, from, token: fromTokenContract, value: amount, eventName } = transaction
|
||||
let vault = false
|
||||
if (!eventName) {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "NotVaultedOrBurnedError: No tokens were vaulted or burned."
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
} else {
|
||||
console.log("Transaction:", transaction)
|
||||
const { contractTo: contract, from, addressTo: fromTokenContract, value: amt, log: eventName } = transaction
|
||||
let vault = false
|
||||
if (!eventName) {
|
||||
output = "NotVaultedOrBurnedError: No tokens were vaulted or burned."
|
||||
res.send(output)
|
||||
return
|
||||
} else {
|
||||
console.log("Event:", eventName)
|
||||
if (eventName.toString() === "BridgeBurned") {
|
||||
vault = false
|
||||
} else if (eventName.toString() === "VaultDeposit") {
|
||||
vault = true
|
||||
}
|
||||
if (eventName.toString() === "BridgeBurned") {
|
||||
vault = false
|
||||
} else if (eventName.toString() === "VaultDeposit") {
|
||||
vault = true
|
||||
}
|
||||
// To prove user signed we recover signer for (msg, sig) using testSig which rtrns address which must == toTargetAddr or return error
|
||||
let signerAddress = ""
|
||||
}
|
||||
|
||||
// To prove user signed we recover signer for (msg, sig) using testSig which rtrns address which must == toTargetAddr or return error
|
||||
let signerAddress = ""
|
||||
try {
|
||||
signerAddress = w3From.eth.accounts.recover(msg, msgSig) //best on server
|
||||
} catch (err) {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "can not recover signer from msgSig"
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
console.log("signerAddress:", signerAddress.toString().toLowerCase(), "From Address:", from.toString().toLowerCase())
|
||||
// Bad signer (test transaction signer must be same as burn transaction signer) => exit, front run attempt
|
||||
let signerOk = false
|
||||
if (signerAddress.toString().toLowerCase() != from.toString().toLowerCase()) {
|
||||
console.log("*** Possible front run attempt, message signer not transaction sender ***")
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "NullToNetIDHashError: No to netId sent."
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
} else {
|
||||
signerOk = true
|
||||
}
|
||||
|
||||
// If signerOk we use the toTargetAddrHash provided, else we hash the from address.
|
||||
toTargetAddrHash = signerOk ? toTargetAddrHash : Web3.utils.keccak256(from)
|
||||
// console.log("token contract:", fromTokenContract.toLowerCase(), "fromTokenConAddr", fromTokenConAddr.toLowerCase(), "contract", contract.toLowerCase(), "frombridgeConAddr", frombridgeConAddr.toLowerCase())
|
||||
// Token was burned.
|
||||
const _decimals = DECIMALS[tokenName] ?? "18"
|
||||
if (fromTokenContract.toLowerCase() === fromTokenConAddr.toLowerCase() && teleporter.toLowerCase() === frombridgeConAddr.toLowerCase()) {
|
||||
// console.log("fromTokenConAddr", fromTokenConAddr, "tokenAddrHash", tokenAddrHash)
|
||||
//Produce signature for minting approval.
|
||||
try {
|
||||
signerAddress = w3From.eth.accounts.recover(msg, msgSig) //best on server
|
||||
const { signature, mpcSigner } = await hashAndSignTx(amount.toString(), w3From, vault, txInfo, _decimals)
|
||||
//NOTE: For private transactions, store only the sig.
|
||||
const output = {
|
||||
fromTokenContractAddress: fromTokenContract,
|
||||
contract: teleporter,
|
||||
from: toTargetAddrHash,
|
||||
tokenAmt: amount,
|
||||
signature: signature,
|
||||
mpcSigner: mpcSigner,
|
||||
hashedTxId: evmTxHash,
|
||||
tokenAddrHash: tokenAddrHash,
|
||||
vault: vault
|
||||
}
|
||||
await saveEvmTxHash({
|
||||
chainType: "evm",
|
||||
txId: txid,
|
||||
amount: amount.toString(),
|
||||
signature,
|
||||
hashedTxId: evmTxHash
|
||||
})
|
||||
res.status(200).json({
|
||||
status: true,
|
||||
data: output
|
||||
})
|
||||
return
|
||||
} catch (err) {
|
||||
console.log("cannt recover signer from msgSig")
|
||||
return res.status(400).json("cannt recover signer from msgSig")
|
||||
}
|
||||
console.log("signerAddress:", signerAddress.toString().toLowerCase(), "From Address:", from.toString().toLowerCase())
|
||||
// Bad signer (test transaction signer must be same as burn transaction signer) => exit, front run attempt
|
||||
let signerOk = false
|
||||
if (signerAddress.toString().toLowerCase() != from.toString().toLowerCase()) {
|
||||
console.log("*** Possible front run attempt, message signer not transaction sender ***")
|
||||
output = "NullToNetIDHashError: No to netId sent."
|
||||
res.send(output)
|
||||
return
|
||||
} else {
|
||||
signerOk = true
|
||||
}
|
||||
|
||||
// If signerOk we use the toTargetAddrHash provided, else we hash the from address.
|
||||
toTargetAddrHash = signerOk ? toTargetAddrHash : Web3.utils.keccak256(from)
|
||||
// console.log("token contract:", fromTokenContract.toLowerCase(), "fromTokenConAddr", fromTokenConAddr.toLowerCase(), "contract", contract.toLowerCase(), "frombridgeConAddr", frombridgeConAddr.toLowerCase())
|
||||
// Token was burned.
|
||||
if (fromTokenContract.toLowerCase() === fromTokenConAddr.toLowerCase() && contract.toLowerCase() === frombridgeConAddr.toLowerCase()) {
|
||||
// console.log("fromTokenConAddr", fromTokenConAddr, "tokenAddrHash", tokenAddrHash)
|
||||
//Produce signature for minting approval.
|
||||
try {
|
||||
sig = (await hashAndSignTx(w3From.utils.toWei(amt.toString(), "ether"), w3From, vault, txInfo)) as string
|
||||
//NOTE: For private transactions, store only the sig.
|
||||
output = { fromTokenContractAddress: fromTokenContract, contract: contract, from: toTargetAddrHash, tokenAmt: amt, signature: sig, hashedTxId: txid, tokenAddrHash: tokenAddrHash, vault: vault }
|
||||
return res.send(output)
|
||||
} catch (err) {
|
||||
if (err === "AlreadyMintedError") {
|
||||
console.log(err)
|
||||
output = { error: err + " It appears these coins were already bridged." }
|
||||
} else if (err === "GasTooLowError") {
|
||||
console.log(err)
|
||||
output = { error: err + " Try setting higher gas prices. Do you have enough tokens to pay for fees?" }
|
||||
} else {
|
||||
console.log(err)
|
||||
output = { error: err }
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
let output: any
|
||||
if (err === "AlreadyMintedError") {
|
||||
console.log(err)
|
||||
output = { status: false, msg: err + " It appears these coins were already bridged." }
|
||||
} else if (err === "GasTooLowError") {
|
||||
console.log(err)
|
||||
output = { status: false, msg: err + " Try setting higher gas prices. Do you have enough tokens to pay for fees?" }
|
||||
} else {
|
||||
console.log(err)
|
||||
output = { status: false, msg: err }
|
||||
}
|
||||
} else {
|
||||
output = { error: "ContractMisMatchError: bad token or bridge contract address." }
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
const output = {
|
||||
status: false,
|
||||
msg: "ContractMisMatchError: bad token or bridge contract address."
|
||||
}
|
||||
res.json(output)
|
||||
return
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
const getEVMTx = async (txh: string, w3From: Web3<RegisteredSubscription>) => {
|
||||
// console.log("In getEVMTx", "txid:", txh)
|
||||
/**
|
||||
* check relay attack
|
||||
* @param evmTxHash
|
||||
* @returns object { status, data }
|
||||
*/
|
||||
const checkStealthSignature = async (evmTxHash: string) => {
|
||||
console.log("Searching for txid:", evmTxHash)
|
||||
try {
|
||||
const transaction = await w3From.eth.getTransaction(txh)
|
||||
const transactionReceipt = await w3From.eth.getTransactionReceipt(txh)
|
||||
const data = await prisma.teleporter.findUnique({
|
||||
where: { hashedTxId: evmTxHash }
|
||||
})
|
||||
console.log("Find Stealth Hash: ", data)
|
||||
if (data) {
|
||||
return Promise.resolve({ status: true, data: data })
|
||||
} else {
|
||||
// not a replay
|
||||
return Promise.resolve({ status: false, data })
|
||||
}
|
||||
} catch (err) {
|
||||
return Promise.resolve({ status: false, data: null })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* save Tx info to db
|
||||
* @param data
|
||||
*/
|
||||
const saveEvmTxHash = async (data: { chainType: string; txId: string; amount: string; signature: string; hashedTxId: string }) => {
|
||||
try {
|
||||
const _tx = await prisma.teleporter.findUnique({
|
||||
where: { hashedTxId: data.hashedTxId }
|
||||
})
|
||||
if (_tx) {
|
||||
console.log("Already Existed Tx")
|
||||
} else {
|
||||
await prisma.teleporter.create({ data })
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
console.log("Failed to save tx to db")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get EVM transaction
|
||||
* @param txHash
|
||||
* @param w3From
|
||||
* @returns
|
||||
*/
|
||||
const getEVMTx = async (txHash: string, w3From: Web3<RegisteredSubscription>) => {
|
||||
try {
|
||||
const transaction = await w3From.eth.getTransaction(txHash)
|
||||
const transactionReceipt = await w3From.eth.getTransactionReceipt(txHash)
|
||||
if (transaction != null && transactionReceipt != null && transaction != undefined && transactionReceipt != undefined) {
|
||||
// console.log("Transaction:", transaction, "Transaction Receipt:", transactionReceipt)
|
||||
const tx = { ...transaction, ...transactionReceipt }
|
||||
if (transactionReceipt.logs.length === 0) {
|
||||
throw new Error("getEVMTXError: there was a problem with the transaction receipt.")
|
||||
}
|
||||
const addrTo = transactionReceipt.logs.length > 0 ? transactionReceipt.logs[0].address : transactionReceipt.to
|
||||
let tokenAmt = parseInt(transaction.input.slice(74, 138), 16) / 10 ** 18
|
||||
tokenAmt -= tokenAmt * 0.008
|
||||
const contractTo = transaction.to
|
||||
// console.log({ transaction })
|
||||
// const addrTo = transactionReceipt.logs.length > 0 ? transactionReceipt.logs[0].address : transactionReceipt.to
|
||||
const teleporter = String(transactionReceipt?.to)
|
||||
|
||||
const _addressOfLog = String(transactionReceipt?.logs[0]?.address)
|
||||
const _addressToken = _addressOfLog.toLowerCase() === teleporter.toLowerCase() ? "0x0000000000000000000000000000000000000000" : _addressOfLog
|
||||
|
||||
console.log("fromTokenAddress: =======>", _addressToken)
|
||||
// console.log({ addrTo, log0: transactionReceipt.logs[0] })
|
||||
// let tokenAmt = parseInt(transaction.input.slice(74, 138), 16)
|
||||
// console.log(tokenAmt)
|
||||
// tokenAmt -= tokenAmt * 0.008
|
||||
const from = transaction.from
|
||||
let amount: number = 0
|
||||
const abi = ["event BridgeBurned(address caller, uint256 amt)", "event VaultDeposit(address depositor, uint256 amt)"]
|
||||
const iface = new Interface(abi)
|
||||
const eventLog = tx.logs
|
||||
let logName: string = ""
|
||||
let _eventName: string = ""
|
||||
// console.log("Log Length:", eventLog.length)
|
||||
for (const _event of eventLog) {
|
||||
try {
|
||||
//@ts-expect-error "_event type not matching"
|
||||
const log = iface.parseLog(_event)
|
||||
// console.log("log", log.name)
|
||||
logName = log.name
|
||||
_eventName = log.name
|
||||
} catch (error) {
|
||||
console.log("EventNotFoundError in log number:", _event)
|
||||
// console.log(`EventNotFoundError in log number:`, _event)
|
||||
}
|
||||
}
|
||||
|
||||
amount = transactionReceipt.logs.length > 0 && transactionReceipt.logs[0].data == "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ? 0 : Number(transactionReceipt.logs[0].data)
|
||||
amount = Number(Web3.utils.fromWei(amount.toLocaleString("fullwide", { useGrouping: false }).toString(), "ether"))
|
||||
|
||||
// amount = transactionReceipt.logs.length > 0 && transactionReceipt.logs[0].data == "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ? 0 : Number(transactionReceipt.logs[0].data)
|
||||
// amount = Number(Web3.utils.fromWei(amount.toLocaleString("fullwide", { useGrouping: false }).toString(), "ether"))
|
||||
const _tokenAmount = transactionReceipt.logs.length === 1 ? String(transactionReceipt.logs[0].data).substring(66) : String(transactionReceipt.logs[1].data).substring(66)
|
||||
// const amount = transactionReceipt.logs.length === 1 ? Number('0x' + String(transactionReceipt.logs[0]).substring(66)) : Number('0x' + String(transactionReceipt.logs[1]).substring(66))
|
||||
const _amount = Number("0x" + _tokenAmount)
|
||||
const transactionObj = {
|
||||
contractTo,
|
||||
addressTo: addrTo,
|
||||
teleporter, // source teleporter address
|
||||
token: _addressToken,
|
||||
from,
|
||||
tokenAmount: tokenAmt,
|
||||
log: logName,
|
||||
value: amount
|
||||
// tokenAmount: tokenAmt,
|
||||
eventName: _eventName,
|
||||
value: _amount
|
||||
}
|
||||
return transactionObj
|
||||
}
|
||||
|
||||
@@ -36,9 +36,8 @@ export const signClient = async (i: number, msgHash: string, txInfo: string[]) =
|
||||
const [txid, fromNetId, toNetIdHash, tokenName, tokenAddrHash, toTargetAddrHash, msgSig, nonce] = txInfo
|
||||
const txidNonce = txid + nonce
|
||||
const list = await find("name", `${signClientName} ${signSmManager}`)
|
||||
console.log("list", list);
|
||||
if (list.length > 0) {
|
||||
console.log("clientAlreadyRunning", list)
|
||||
console.log("clientAlreadyRunning:::", list)
|
||||
try {
|
||||
const x = list.length === 1 ? 0 : 1
|
||||
const uptimeCmd = "ps -p " + list[x].pid + " -o etime"
|
||||
@@ -59,7 +58,7 @@ export const signClient = async (i: number, msgHash: string, txInfo: string[]) =
|
||||
await killSigner(String(p.pid))
|
||||
}
|
||||
const cmd = `./target/release/examples/${signClientName} ${signSmManager} ${keyStore} ${msgHash}`
|
||||
await exec(cmd, { cwd: __dirname + "/multiparty", shell: '/bin/bash' }) // Make sure it"s dead
|
||||
await exec(cmd, { cwd: __dirname + "/multiparty", shell: "/bin/bash" }) // Make sure it"s dead
|
||||
} catch (err) {
|
||||
console.log("Partial signature process may not have exited:", err)
|
||||
resolve(signClient(i, msgHash, txInfo))
|
||||
@@ -145,32 +144,32 @@ export const signClient = async (i: number, msgHash: string, txInfo: string[]) =
|
||||
* @param txProcMap
|
||||
* @returns
|
||||
*/
|
||||
//will become MPC
|
||||
export const signMsg = async (message: string, web3: Web3<RegisteredSubscription>, txInfo: string[]) => {
|
||||
try {
|
||||
// const sig = web3.eth.accounts.sign(message, "0xb0bffa4504c56ae708e1fed516aa433f8926fd1dfd667ebd33667611ab02ac0f")
|
||||
// const { signature, messageHash, r, s, v } = sig
|
||||
// console.log("MPC Address:", web3.eth.accounts.recover(message, signature))
|
||||
// console.log("MPC Address:", web3.eth.accounts.recover(message, v, r, s))
|
||||
// const myMsgHashAndPrefix = web3.eth.accounts.hashMessage(message)
|
||||
// const netSigningMsg = message
|
||||
// return signature
|
||||
const sig = web3.eth.accounts.sign(message, "0xb0bffa4504c56ae708e1fed516aa433f8926fd1dfd667ebd33667611ab02ac0f")
|
||||
const { signature, messageHash, r, s, v } = sig
|
||||
const myMsgHashAndPrefix = web3.eth.accounts.hashMessage(message)
|
||||
const netSigningMsg = myMsgHashAndPrefix.substr(2)
|
||||
const i = 0
|
||||
try {
|
||||
const { signature, r, s, v } = (await signClient(i, netSigningMsg, txInfo)) as any
|
||||
console.log("SIGNATURE =================> ", { netSigningMsg, signature, r, s, v })
|
||||
try {
|
||||
console.log("MPC Address:", recoverAddress(myMsgHashAndPrefix, signature))
|
||||
} catch (err) {
|
||||
console.log("err: ", err)
|
||||
}
|
||||
return Promise.resolve(signature)
|
||||
} catch (err) {
|
||||
console.log("Error:", err)
|
||||
return Promise.reject("signClientError:")
|
||||
}
|
||||
const signer = recoverAddress(myMsgHashAndPrefix, signature)
|
||||
console.log("MPC Address:", signer)
|
||||
return Promise.resolve({ signature, signer })
|
||||
|
||||
// const myMsgHashAndPrefix = web3.eth.accounts.hashMessage(message)
|
||||
// const netSigningMsg = myMsgHashAndPrefix.substr(2)
|
||||
// const i = 0
|
||||
// try {
|
||||
// const { signature, r, s, v } = (await signClient(i, netSigningMsg, txInfo)) as any
|
||||
// let signer = ""
|
||||
// try {
|
||||
// signer = recoverAddress(myMsgHashAndPrefix, signature)
|
||||
// console.log("MPC Address:", signer)
|
||||
// } catch (err) {
|
||||
// console.log("err: ", err)
|
||||
// }
|
||||
// return Promise.resolve({ signature, signer })
|
||||
// } catch (err) {
|
||||
// console.log("Error:", err)
|
||||
// return Promise.reject("signClientError:")
|
||||
// }
|
||||
} catch (err) {
|
||||
console.log("Error:", err)
|
||||
return Promise.reject(err)
|
||||
@@ -187,8 +186,8 @@ export const signMsg = async (message: string, web3: Web3<RegisteredSubscription
|
||||
* @param vault
|
||||
* @returns string
|
||||
*/
|
||||
export const concatMsg = (amt: string, targetAddressHash: string, txid: string, toContractAddress: string, toChainIdHash: string, vault: boolean) => {
|
||||
return amt + targetAddressHash + txid + toContractAddress + toChainIdHash + vault
|
||||
export const concatMsg = (amount: string, targetAddressHash: string, txid: string, toContractAddress: string, toChainIdHash: string, decimals: string, vault: boolean) => {
|
||||
return amount + targetAddressHash + txid + toContractAddress + toChainIdHash + decimals + vault
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,23 +195,23 @@ export const concatMsg = (amt: string, targetAddressHash: string, txid: string,
|
||||
* @param web3
|
||||
* @param vault
|
||||
* @param txInfo
|
||||
* @param txProcMap
|
||||
* @param _decimals
|
||||
*/
|
||||
export const hashAndSignTx = async (amt: string, web3: Web3<RegisteredSubscription>, vault: boolean, txInfo: string[]) => {
|
||||
export const hashAndSignTx = async (amount: string, web3: Web3<RegisteredSubscription>, vault: boolean, txInfo: string[], _decimals: string) => {
|
||||
try {
|
||||
const toTargetAddrHash = txInfo[5]
|
||||
const txid = txInfo[0]
|
||||
const txHash = txInfo[0]
|
||||
const toChainIdHash = txInfo[2]
|
||||
const toContractAddress = txInfo[4]
|
||||
const nonce = txInfo[7]
|
||||
const message = concatMsg(amt, toTargetAddrHash, txid, toContractAddress, toChainIdHash, vault)
|
||||
// console.log("Message:", message)
|
||||
const message = concatMsg(amount, toTargetAddrHash, txHash, toContractAddress, toChainIdHash, _decimals, vault)
|
||||
|
||||
const hash = web3.utils.soliditySha3(message)
|
||||
const sig = await signMsg(hash, web3, txInfo)
|
||||
return Promise.resolve(sig)
|
||||
const { signature, signer } = await signMsg(hash, web3, txInfo)
|
||||
return Promise.resolve({ signature, mpcSigner: signer })
|
||||
} catch (err) {
|
||||
if (err.toString().includes("invalid point")) {
|
||||
hashAndSignTx(amt, web3, vault, txInfo)
|
||||
hashAndSignTx(amount, web3, vault, txInfo, _decimals)
|
||||
} else {
|
||||
console.log(err)
|
||||
return Promise.reject(err)
|
||||
|
||||
Generated
+2395
-41
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user