diff --git a/.gitignore b/.gitignore index ad644521..11be0792 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ src/test.ts .env* test* *.DS_Store +src/helpers/elrond/elrond-test.ts diff --git a/package.json b/package.json index 9efdb5b5..42a4307a 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@make-software/ces-js-parser": "^1.3.1", "@multiversx/sdk-core": "^12.9.0", "@multiversx/sdk-extension-provider": "^3.0.0", - "@multiversx/sdk-network-providers": "^2.1.0", + "@multiversx/sdk-network-providers": "^2.2.0", "@multiversx/sdk-wallet": "^4.2.0", "@project-serum/anchor": "^0.25.0-beta.1", "@randlabs/myalgo-connect": "^1.1.1", @@ -61,7 +61,7 @@ "@walletconnect/client": "^1.7.0", "algosdk": "=2.2.0", "aptos": "^1.6.0", - "axios": "^0.21.1", + "axios": "^1.6.2", "base64url": "^3.0.1", "bignumber.js": "=9.0.1", "bn.js": "^5.2.1", diff --git a/src/config.ts b/src/config.ts index 975f50a0..730cd887 100644 --- a/src/config.ts +++ b/src/config.ts @@ -30,7 +30,7 @@ export namespace AppConfigs { heartbeatUri: "https://tools.xp.network/testnet-pinger/", wrappedNftPrefix: "https://tools.xp.network/testnet-wnft/", //"https://bridge-wnftapi.herokuapp.com/", scVerifyUri: "https://tools.xp.network/testnet-sc-verify/", - storageContract: "0x54194d68528B72EEb96d0a7ce7ffabaF14bD250D", //"0x8F1fd3a5DbBd5659579aE7d9b258CC6CbcB3e53d", //"0xDb2a42f40158B1Cb29703e2a95a6fa3094294f05", + storageContract: "0x0263A038014505881E33d4201950fa11c29793F3", //"0x8F1fd3a5DbBd5659579aE7d9b258CC6CbcB3e53d", //"0xDb2a42f40158B1Cb29703e2a95a6fa3094294f05", storegeNetwork: "https://optimism-goerli.publicnode.com", network: "testnet", }; diff --git a/src/consts.ts b/src/consts.ts index 36bfa7c1..34af0252 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -3,6 +3,7 @@ import { ElrondParams, ElrondHelper, } from "./helpers/elrond/elrond"; + import { tronHelperFactory, TronParams, TronHelper } from "./helpers/tron"; import { web3HelperFactory, Web3Params, Web3Helper } from "./helpers/evm/web3"; import { HederaHelperFactory } from "./helpers/hedera/hedera_refactor"; @@ -47,7 +48,7 @@ export enum TestNetRpcUri { ELROND = "https://devnet-gateway.multiversx.com", HECO = "https://http-testnet.hecochain.com", BSC = "https://data-seed-prebsc-1-s1.binance.org:8545", - ROPSTEN = "https://ultra-light-patina.ethereum-sepolia.discover.quiknode.pro/6f98178f32c668af8ee4bb1cc4b8b9308e29367b/", + ROPSTEN = "https://ethereum-sepolia.blockpi.network/v1/rpc/public", //"https://ultra-light-patina.ethereum-sepolia.discover.quiknode.pro/6f98178f32c668af8ee4bb1cc4b8b9308e29367b/", AVALANCHE = "https://api.avax-test.network/ext/bc/C/rpc", POLYGON = "https://polygon-mumbai.blockpi.network/v1/rpc/public", FANTOM = "https://rpc.testnet.fantom.network/", @@ -287,20 +288,8 @@ export enum ChainType { } export const CHAIN_INFO: ChainInfo = new Map(); -CHAIN_INFO.set(Chain.ELROND, { - name: "Elrond", - nonce: 2, - v3_chainId: v3_ChainId.ELROND, - decimals: Decimals.EGLD, - constructor: elrondHelperFactory, - blockExplorerUrl: "https://explorer.elrond.com/transactions/", - blockExplorerUrlAddr: "https://explorer.elrond.com/address/", - tnBlockExplorerUrl: "https://devnet-explorer.multiversx.com/transactions/", - tnBlockExplorerUrlAddr: "https://devnet-explorer.multiversx.com/accounts/", - currency: SupportedCurrency.EGLD, - currencySymbol: SupportedCurrencyName.EGLD, - type: ChainType.ELROND, -}); +console.log(elrondHelperFactory, "elrondHelperFactory"); + CHAIN_INFO.set(Chain.HECO, { name: "HECO", nonce: 3, @@ -935,3 +924,19 @@ CHAIN_INFO.set(Chain.FINDORA, { tnBlockExplorerUrlAddr: "https://testnet-anvil.evm.findorascan.io/address/", tnChainId: 2153, }); +setTimeout(() => { + CHAIN_INFO.set(Chain.ELROND, { + name: "Elrond", + nonce: 2, + v3_chainId: v3_ChainId.ELROND, + decimals: Decimals.EGLD, + constructor: elrondHelperFactory, + blockExplorerUrl: "https://explorer.elrond.com/transactions/", + blockExplorerUrlAddr: "https://explorer.elrond.com/address/", + tnBlockExplorerUrl: "https://devnet-explorer.multiversx.com/transactions/", + tnBlockExplorerUrlAddr: "https://devnet-explorer.multiversx.com/accounts/", + currency: SupportedCurrency.EGLD, + currencySymbol: SupportedCurrencyName.EGLD, + type: ChainType.ELROND, + }); +}, 300); diff --git a/src/factory/factories.ts b/src/factory/factories.ts index f71dba66..71c8c7f0 100644 --- a/src/factory/factories.ts +++ b/src/factory/factories.ts @@ -68,7 +68,7 @@ export namespace ChainFactoryConfigs { elrondApi: "https://devnet-api.multiversx.com", elrondIndex: "https://devnet-index.multiversx.com", v3_bridge: - "erd1qqqqqqqqqqqqqpgqmzkpcys59zu6txccjkl7v3dusch5plc36n9sfla9y0", //"erd1qqqqqqqqqqqqqpgqthnm9plsj3he2jqky672vty4adg02hg26n9s3g8rdm", //"erd1qqqqqqqqqqqqqpgqghvly0npf6ewpmzh47ud76ssh6nppu4e7hnses7qlz", + "erd1qqqqqqqqqqqqqpgqtsw8s3evjjyqqa2j2tfn9yvufqskdv236n9s2a06h9", //"erd1qqqqqqqqqqqqqpgqthnm9plsj3he2jqky672vty4adg02hg26n9s3g8rdm", //"erd1qqqqqqqqqqqqqpgqghvly0npf6ewpmzh47ud76ssh6nppu4e7hnses7qlz", notifier, nonce: Chain.ELROND, feeMargin, @@ -286,7 +286,7 @@ export namespace ChainFactoryConfigs { erc1155Minter: "0x5dA3b7431f4581a7d35aEc2f3429174DC0f2A2E1", erc721Minter: "0x97CD6fD6cbFfaa24f5c858843955C2601cc7F2b9", erc1155_addr: "0x22A23E09dBa96c8e10A57a53Abc1227fAe06b4D1", //"0xb5278A4808e2345A3B9d08bAc8909A121aFaEBB3", - v3_bridge: "0xF468FdB229acA4Df52e1A280b84221F7e1BE99bf", //"0x3fCA19cd73F774E13433a86C0E7996E3D291d29E", //"0x64F90C25A0802E64D0593518fa26FfBc9D78564F", + v3_bridge: "0xBBF8B4601ebE9d14aDa11220749F71030012A57a", //"0xF468FdB229acA4Df52e1A280b84221F7e1BE99bf", //"0x3fCA19cd73F774E13433a86C0E7996E3D291d29E", //"0x64F90C25A0802E64D0593518fa26FfBc9D78564F", nonce: Chain.BSC, feeMargin, }, @@ -323,7 +323,7 @@ export namespace ChainFactoryConfigs { erc1155Minter: "0x539daC37CF7d918fe93897D4C02277a220cE3a6e", erc721Minter: "0x833A2efC56B3625829727bb9D15F70cd2971Cd84", minter_addr: "0xDb199384BA327126653Ab8AcAB1fB3D5d88E2Ee2", - v3_bridge: "0xbc24902a64A50a047F621BB0Cf5efDFb0ae441E0", + v3_bridge: "0xbcA0587e714Ed9B312aec735AbE28C763BfC6442", nonce: Chain.ETHEREUM, feeMargin, }, diff --git a/src/factory/utils.ts b/src/factory/utils.ts index 5f1bff07..34701cd4 100644 --- a/src/factory/utils.ts +++ b/src/factory/utils.ts @@ -2,6 +2,7 @@ import { NftInfo, FullChain } from ".."; import { CHAIN_INFO, ChainType, Chain } from "../consts"; import axios from "axios"; import BigNumber from "bignumber.js"; +import { V3_ChainId } from "../type-utils"; export const _headers = { "Content-Type": "application/json", @@ -167,3 +168,8 @@ export const decodeBase64Array = (encodedArray: string[]): string[] | null => { return Buffer.from(encodedString, "base64").toString("utf-8"); }); }; + +export const v3BridgeIdToNonce = (id: V3_ChainId) => + Array.from(CHAIN_INFO.values()) + .find((c) => c.v3_chainId === id)! + .nonce.toString(); diff --git a/src/helpers/chain.ts b/src/helpers/chain.ts index 0e6553ee..a01dd33f 100644 --- a/src/helpers/chain.ts +++ b/src/helpers/chain.ts @@ -97,6 +97,10 @@ export interface GetTokenInfo { getTokenInfo(depTrxData: DepTrxData): Promise; } +export interface GetNftOrigin { + getNftOrigin(address: string): Promise<{ origin: string; contract?: string }>; +} + export interface ClaimV3NFT { claimV3NFT( sender: Signer, diff --git a/src/helpers/elrond/elrond-test.ts b/src/helpers/elrond/elrond-test.ts index d3126ab1..2fc45039 100644 --- a/src/helpers/elrond/elrond-test.ts +++ b/src/helpers/elrond/elrond-test.ts @@ -1,6 +1,6 @@ //import { Mnemonic } from "@elrondnetwork/erdjs"; - -/*import { +/* +import { AbiRegistry, SmartContract, Address, @@ -9,13 +9,26 @@ TransactionPayload, ResultsParser, BigUIntValue, + StructType, + BytesType, + FieldDefinition, + BigUIntType, + AddressType, + Field, + BytesValue, + Struct, + VariadicValue, + AddressValue, } from "@multiversx/sdk-core"; import { ProxyNetworkProvider, ApiNetworkProvider } from "@multiversx/sdk-network-providers"; import { UserSigner, Mnemonic } from "@multiversx/sdk-wallet"; import abi from "./v3Bridge_abi.json"; -import { decodeBase64Array } from "../../factory"; -import axios from "axios"; +import { Nonce } from "@multiversx/sdk-network-providers/out/primitives"; +//import { decodeBase64Array } from "../../factory"; +//import axios from "axios"; import BigNumber from "bignumber.js"; +import { decodeBase64Array } from "../../factory"; +import { inspect } from "node:util"; const f = Mnemonic.fromString( `evidence liberty culture stuff canal minute toward trash boil cry verb recall during citizen social upper budget ranch distance business excite fox icon tool` @@ -24,13 +37,13 @@ const proxyNetworkProvider = new ProxyNetworkProvider("https://devnet-gateway.mu const apiNetworkProvider = new ApiNetworkProvider("https://devnet2-api.multiversx.com"); const signer = new UserSigner(f.deriveKey()); -const bridgeAddress = new Address("erd1qqqqqqqqqqqqqpgqghvly0npf6ewpmzh47ud76ssh6nppu4e7hnses7qlz"); +const bridgeAddress = new Address("erd1qqqqqqqqqqqqqpgqtsw8s3evjjyqqa2j2tfn9yvufqskdv236n9s2a06h9"); const abiRegistry = AbiRegistry.create(abi); const bridgeContract = new SmartContract({ address: bridgeAddress, abi: abiRegistry, }); -bridgeContract; + const collectionName = "Alex"; const collectionTicker = "ALX"; const collectionIdentifier = "ALX-afef0b"; @@ -188,6 +201,7 @@ async function transferToSc( receiver: signer.getAddress(), chainID: "D", }); + const nonce1 = account.getNonceThenIncrement(); tx3.setNonce(nonce1); @@ -199,6 +213,98 @@ async function transferToSc( console.log("Hash:", txHash); } +async function claim(account: Account, signer: UserSigner) { + const structClaimData = new StructType("ClaimData", [ + new FieldDefinition("token_id", "name of the nft", new BytesType()), + new FieldDefinition("source_chain", "attributes of the nft", new BytesType()), + new FieldDefinition("destination_chain", "attributes of the nft", new BytesType()), + new FieldDefinition("destination_user_address", "attributes of the nft", new AddressType()), + new FieldDefinition("source_nft_contract_address", "attributes of the nft", new BytesType()), + new FieldDefinition("name", "attributes of the nft", new BytesType()), + new FieldDefinition("symbol", "attributes of the nft", new BytesType()), + new FieldDefinition("royalty", "attributes of the nft", new BigUIntType()), + new FieldDefinition("royalty_receiver", "attributes of the nft", new AddressType()), + new FieldDefinition("attrs", "attributes of the nft", new BytesType()), + new FieldDefinition("transaction_hash", "attributes of the nft", new BytesType()), + new FieldDefinition("token_amount", "attributes of the nft", new BigUIntType()), + new FieldDefinition("nft_type", "attributes of the nft", new BytesType()), + new FieldDefinition("fee", "attributes of the nft", new BigUIntType()), + ]); + + //copied from validator logs + const claimData = { + tokenId: "33", + sourceChain: "BSC", + destinationChain: "MULTIVERSX", + destinationUserAddress: "erd1ymdj4ze52a0tmcjzeyhcntzaf5uxpn2d6t203yreh6qx6fqeftgqmz9ly6", + sourceNftContractAddress: "0xc679bdad7c2a34ca93552eae75e4bc03bf505adc", + name: "Istra", + symbol: "NSA", + royalty: "0", + royaltyReceiver: "9fb927c978225cb7a93b8b3cd8d8423e176e009dc284c536d9c4372bbe128487", + metadata: "https://meta.polkamon.com/meta?id=10002366748", + transactionHash: "0x4e7cc1b533361fc39f013391c6fead3f0a55a4656f8e7f1a84af7740ff5a2abf", + tokenAmount: "1", + nftType: "singular", + fee: "100000000000000", + }; + + //sig copied validator logs + const signature = { + sig: "0xdccd31367579bfd82e46881e28c2201f7e9e58327e1c4366e972c170ad9b3b1924861101446bdc8ea1c5b364361fa12cabcea32c473e2f759a01e699e24bdc07", + public_key: "9fb927c978225cb7a93b8b3cd8d8423e176e009dc284c536d9c4372bbe128487", + }; + + const claimDataArgs = new Struct(structClaimData, [ + new Field(new BytesValue(Buffer.from(new Nonce(Number(claimData.tokenId)).hex(), "hex")), "token_id"), + new Field(new BytesValue(Buffer.from(claimData.sourceChain)), "source_chain"), + new Field(new BytesValue(Buffer.from(claimData.destinationChain)), "destination_chain"), + new Field(new AddressValue(new Address(claimData.destinationUserAddress)), "destination_user_address"), + new Field(new BytesValue(Buffer.from(claimData.sourceNftContractAddress)), "source_nft_contract_address"), + new Field(new BytesValue(Buffer.from(claimData.name)), "name"), + new Field(new BytesValue(Buffer.from("N" + claimData.sourceChain.toUpperCase())), "symbol"), + new Field(new BigUIntValue(new Nonce(Number(claimData.royalty)).hex()), "royalty"), + new Field(new AddressValue(new Address(claimData.royaltyReceiver)), "royalty_receiver"), + new Field(new BytesValue(Buffer.from(claimData.metadata)), "attrs"), + new Field(new BytesValue(Buffer.from(claimData.transactionHash)), "transaction_hash"), + new Field(new BigUIntValue(claimData.tokenAmount), "token_amount"), + new Field(new BytesValue(Buffer.from(claimData.nftType)), "nft_type"), + new Field(new BigUIntValue(claimData.fee), "fee"), + ]); + + const data = [ + claimDataArgs, + [ + { + public_key: new AddressValue(new Address(Buffer.from(signature.public_key, "hex"))), + sig: new BytesValue(Buffer.from(signature.sig.replace(/^0x/, ""), "hex")), + }, + ], + VariadicValue.fromItems( + new BytesValue( + Buffer.from( + "https://drive.polychainmonsters.com/ipfs/QmXBAiT4um5WSJZfoJ1arCbcJh89yBEYvi17bVM91rj3t4", + "utf-8" + ) + ), + new BytesValue(Buffer.from(claimData.metadata, "utf-8")) + ), + ]; + + const transaction = bridgeContract.methods + .claimNft721(data) + .withSender(signer.getAddress()) + .withNonce(account.getNonceThenIncrement()) + .withChainID("D") + .withGasLimit(6_000_000_00) + .withValue(new BigUIntValue(new BigNumber("50000000000000000"))) + .buildTransaction(); + + transaction.applySignature(await signer.sign(transaction.serializeForSigning())); + const hash = await proxyNetworkProvider.sendTransaction(transaction); + console.log(hash); +} + const address = new Address("erd1ymdj4ze52a0tmcjzeyhcntzaf5uxpn2d6t203yreh6qx6fqeftgqmz9ly6"); const account = new Account(address); @@ -215,36 +321,39 @@ const account = new Account(address); setSpecialRoles; createNft; transferToSc; + + false && (await claim(account, signer)); //transferToSc(bridgeAddress, account, signer, "ALX-afef0b-01", "01"); - //await createNft("ALX-afef0b-07", address, account, signer); + //await createNft("ALX-afef0b-51", address, account, signer); - const data = { - headers: { - "Content-Type": "application/json", - }, - data: { - _source: ["events"], - query: { - bool: { - should: [ - { - terms: { - originalTxHash: ["6ae4c0fdb82785f7642975b0e1a21b5b3d441c7d74345e06667ea20dcadda150"], - }, - }, - ], - }, - }, - }, - }; - const logs = (await axios.get(`https://devnet-index.multiversx.com/logs/_search`, data))?.data?.hits?.hits[0] - ?._source?.events; + const query = bridgeContract.createQuery({ + func: "originalToDuplicateMapping", + args: [], + //caller: signer.getAddress(), + }); + + const provider = new ProxyNetworkProvider("https://devnet-gateway.multiversx.com"); + + const queryResponse = await provider.queryContract(query); + + const def = bridgeContract.getEndpoint("originalToDuplicateMapping"); + + const { firstValue } = new ResultsParser().parseQueryResponse(queryResponse, def); + const count = firstValue?.valueOf(); + + const decodedMapping = count.map((pair: any) => { + return pair.flatMap((item: any[]) => { + return Object.keys(item).map((key: any) => ({ [key]: Buffer.from(item[key]).toString() })); + }); + }); + + const pair = decodedMapping.find((item: []) => + item.find((obj) => Object.values(obj).find((val) => val === "NSA-42b661")) + ); - console.log(logs); - const x = decodeBase64Array(logs[1].topics) as string[]; + console.log(pair[0].field0, pair[1].field1); - console.log(x, "x"); - signer; + //console.log(decodeBase64Array(res.returnData), "res"); //await createNft("ALX-afef0b-07", address, account, signer); //await createNft("ALX-afef0b-08", address, account, signer); //await createNft("ALX-afef0b-09", address, account, signer); diff --git a/src/helpers/elrond/elrond.ts b/src/helpers/elrond/elrond.ts index ff87483c..9502ca9c 100644 --- a/src/helpers/elrond/elrond.ts +++ b/src/helpers/elrond/elrond.ts @@ -47,16 +47,14 @@ import { BytesValue as XBytesValue, AddressValue as XAddressValue, BigUIntValue as XBigUIntValue, - //BinaryCodec, + ResultsParser, VariadicValue, - //ResultsParser, - //SignableMessage, } from "@multiversx/sdk-core"; import { ExtensionProvider as XExtensionProvider } from "@multiversx/sdk-extension-provider"; -//import { Nonce as XNonce } from "@multiversx/sdk-network-providers/out/primitives"; - +import { Nonce as XNonce } from "@multiversx/sdk-network-providers/out/primitives"; +import { ProxyNetworkProvider } from "@multiversx/sdk-network-providers"; import axios from "axios"; import BigNumber from "bignumber.js"; import { @@ -89,6 +87,7 @@ import { PreTransfer, PreTransferRawTxn, ValidateAddress, + GetNftOrigin, } from "../.."; import { EvNotifier } from "../../services/notifier"; import { Base64 } from "js-base64"; @@ -260,7 +259,8 @@ export type ElrondHelper = BalanceCheck & LockNFT & ClaimV3NFT & GetClaimData & - GetTokenInfo; + GetTokenInfo & + GetNftOrigin; /** * Create an object implementing cross chain utilities for elrond @@ -288,7 +288,7 @@ export async function elrondHelperFactory( elrondParams: ElrondParams ): Promise { const provider = new ProxyProvider(elrondParams.node_uri); - //const proxyNetworkProvider = new ProxyNetworkProvider(elrondParams.node_uri); + const proxyNetworkProvider = new ProxyNetworkProvider(elrondParams.node_uri); await NetworkConfig.getDefault().sync(provider); const mintContract = new Address(elrondParams.minter_address); const swapContract = new Address(elrondParams.esdt_swap_address); @@ -314,6 +314,28 @@ export async function elrondHelperFactory( elrondParams.elrondIndex ); + let originalContractMapping: any; + const queryResponse = await proxyNetworkProvider + .queryContract( + bridgeContract.createQuery({ + func: "originalToDuplicateMapping", + args: [], + }) + ) + .catch((e) => { + console.log(e, "originalToDuplicateMapping query multivers"); + }); + + if (queryResponse) { + const def = bridgeContract.getEndpoint("originalToDuplicateMapping"); + + const { firstValue } = new ResultsParser().parseQueryResponse( + queryResponse, + def + ); + originalContractMapping = firstValue?.valueOf(); + } + async function notifyValidator( txn: Transaction, sender: string, @@ -987,61 +1009,13 @@ export async function elrondHelperFactory( name: collectionData.name, symbol: depTrxData.sourceNftContractAddress, //image: Base64.decode(nftData?.uris?.at(0) || ""), - royalty: String(nftData.royalties * 100), + royalty: String((nftData.royalties || 0) * 100), }; }, async getClaimData(hash, helpers) { try { - /*const sourceNonce = Array.from(CHAIN_INFO.values()).find((c) => c.v3_chainId === "MULTIVERSX")?.nonce; - - if (!sourceNonce) { - throw new Error("Source chain is undefined"); - } - console.log(sourceNonce, "sourceNonce in elrond"); - - const sourceChain = helpers.get(sourceNonce as ChainNonce); - - const data = ( - await axios(`${elrondParams.elrondApi}/transaction/${hash}?withResults=true`).catch(() => undefined) - )?.data?.data?.transaction; - - // const x = provider.getTransaction(); - - if (!data) { - throw new Error("Failed to get Multiversex trx data"); - } - - const topics = data.logs.events.find((e: any) => e.address === data.sender).topics; - console.log(topics, "topics"); - - const decodedData = decodeBase64Array(topics); - - console.log(decodedData); - - if (!decodedData) { - throw new Error("Failed to get Multiversex trx data"); - } - - const tokenId = String(decodedData[1].charCodeAt(0)); - const destinationChain = decodedData[2] as V3_ChainId; - const destinationUserAddress = decodedData[3]; - const sourceNftContractAddress = decodedData[4]; - const tokenAmount = String(decodedData[5].charCodeAt(0)); - const nftType = decodedData[6] as "singular" | "multiple"; - const sourceChain = decodedData[7] as V3_ChainId;*/ - const decoded = await multiversexApiService.getLockDecodedArgs(hash); - /*const decoded: DepTrxData = { - destinationChain, - destinationUserAddress, - nftType, - sourceChain, - sourceNftContractAddress, - tokenAmount, - tokenId, - };*/ - const sourceNonce = Array.from(CHAIN_INFO.values()).find( (c) => c.v3_chainId === decoded.sourceChain )?.nonce; @@ -1219,9 +1193,14 @@ export async function elrondHelperFactory( "source_nft_contract_address" ), new Field(new XBytesValue(Buffer.from(claimData.name)), "name"), - new Field(new XBytesValue(Buffer.from(claimData.symbol)), "symbol"), new Field( - new XBigUIntValue(Number(claimData.royalty) / 100), + new XBytesValue( + Buffer.from("N" + claimData.sourceChain.toUpperCase()) + ), + "symbol" + ), + new Field( + new XBigUIntValue(new XNonce(Number(claimData.royalty)).hex()), "royalty" ), new Field( @@ -1290,6 +1269,29 @@ export async function elrondHelperFactory( await provider.sendTransaction(txs as unknown as Transaction); return txs; }, + async getNftOrigin(address) { + const native = { origin: String(elrondParams.nonce) }; + if (!originalContractMapping) return native; + + const decodedMapping = originalContractMapping.map((pair: []) => { + return pair.flatMap((item: []) => { + return Object.keys(item).map((key: any) => ({ + [key]: Buffer.from(item[key]).toString(), + })); + }); + }); + + const pair = decodedMapping.find((item: []) => + item.find((obj) => Object.values(obj)?.find((val) => val === address)) + ); + + if (!pair) return native; + + return { + origin: pair[1].field1 as string, + contract: pair[0].field0 as string, + }; + }, }; } diff --git a/src/helpers/evm/web3.ts b/src/helpers/evm/web3.ts index 461619c5..5eb89008 100644 --- a/src/helpers/evm/web3.ts +++ b/src/helpers/evm/web3.ts @@ -62,8 +62,10 @@ import { GetClaimData, ClaimV3NFT, CHAIN_INFO, + GetNftOrigin, + v3BridgeIdToNonce, } from "../.."; -import { ChainNonce } from "../../type-utils"; +import { ChainNonce, V3_ChainId } from "../../type-utils"; import { EvNotifier } from "../../services/notifier"; import { hethers } from "@hashgraph/hethers"; import { txnUnderpricedPolyWorkaround as UnderpricedWorkaround } from "./web3_utils"; @@ -206,7 +208,8 @@ export type Web3Helper = BaseWeb3Helper & LockNFT & ClaimV3NFT & GetClaimData & - GetTokenInfo; + GetTokenInfo & + GetNftOrigin; /** * Create an object implementing minimal utilities for a web3 chain @@ -1216,6 +1219,7 @@ export async function web3HelperFactory( signatureArray, { value: initialClaimData.fee, + gasLimit: "2000000", } ); @@ -1224,5 +1228,24 @@ export async function web3HelperFactory( await tx.wait(); return tx; }, + async getNftOrigin(address) { + const nonce = String(params.nonce); + try { + const bridge = V3Bridge__factory.connect( + params.v3_bridge!, + params.provider + ); + const chain = await bridge.functions.selfChain(); + const res = await bridge.duplicateToOriginalMapping(address, chain[0]); + return { + origin: res.chain + ? v3BridgeIdToNonce(res.chain as V3_ChainId) + : nonce, + contract: res.contractAddress, + }; + } catch { + return { origin: nonce }; + } + }, }; } diff --git a/src/helpers/evm/web3_erc20.ts b/src/helpers/evm/web3_erc20.ts index 36c8d691..4e95f63b 100644 --- a/src/helpers/evm/web3_erc20.ts +++ b/src/helpers/evm/web3_erc20.ts @@ -457,5 +457,8 @@ export async function web3ERC20HelperFactory( async getTokenInfo() { return undefined as any; }, + async getNftOrigin() { + return undefined as any; + }, }; } diff --git a/src/services/multiversex.ts b/src/services/multiversex.ts index dcfcb780..86ec4f29 100644 --- a/src/services/multiversex.ts +++ b/src/services/multiversex.ts @@ -24,6 +24,8 @@ export function multiversexService( baseURL: indexerUrl, }); + index; + return { async getTokenInfo(collection, tokenId) { const nftData = ( @@ -48,31 +50,36 @@ export function multiversexService( return collectionData; }, async getLockDecodedArgs(hash) { - const data = { - headers: { - "Content-Type": "application/json", - }, - data: { - _source: ["events"], - query: { - bool: { - should: [ - { - terms: { - originalTxHash: [hash], - }, + /*const data = { + headers: { + "Content-Type": "application/json", }, - ], - }, - }, - }, - }; - const event = ( - await index("/logs/_search", data) - )?.data?.hits?.hits[0]?._source?.events?.find( - (e: any) => e.identifier === "lock721" - ); + data: { + _source: ["events"], + query: { + bool: { + should: [ + { + terms: { + originalTxHash: [hash], + }, + }, + ], + }, + }, + }, + }; + const event = ( + await index.get("/logs/_search", data).catch((e) => { + console.log(e, "ee"); + return undefined; + }) + )?.data?.hits?.hits[0]?._source?.events?.find((e: any) => e.identifier === "lock721");*/ + const res = await api.get(`/transactions/${hash}?withResults=true`); + const event = res?.data?.results + ?.find((r: any) => r.logs) + ?.logs?.events?.find((e: any) => e.identifier === "lock721"); if (!event) { throw new Error(`Failed to get ${hash} events`); } diff --git a/tsconfig.json b/tsconfig.json index 66714913..7ba039f9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "incremental": false, - "target": "ES2021", + "target": "ES2022", "outDir": "./dist", //"outDir": "../bridge-interface/node_modules/xp.network/dist", //"outDir": "../bridge-tests/node_modules/xp.network/dist", diff --git a/yarn.lock b/yarn.lock index cf0053e7..a360cf37 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1257,12 +1257,12 @@ resolved "https://registry.yarnpkg.com/@multiversx/sdk-extension-provider/-/sdk-extension-provider-3.0.0.tgz#e0e178ee5555f9440457547759621f5c3152c5fa" integrity sha512-xNHLShzimYbMXqEJoiNyB4fNOXQUwSJCzt9FiOA4GdxucJnCgIM25mXtSj2I93cz+KD39QgRjEYep+li/lykOw== -"@multiversx/sdk-network-providers@^2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@multiversx/sdk-network-providers/-/sdk-network-providers-2.1.0.tgz#09972282da05fbdf34b023f4ef669f9a64b9e8d6" - integrity sha512-BiU2R9nu7OKKZckxZ7jjjUbFIyHM9Z6Qera224s9xIel+FjYDDkNCm1qtnvZ5Pc7ftQggFUZ7W/WnEgFhqEZGA== +"@multiversx/sdk-network-providers@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@multiversx/sdk-network-providers/-/sdk-network-providers-2.2.0.tgz#2b8d5fbbc848dbeba38950db2f02340908dfcfd3" + integrity sha512-2n/+7Ap6S9rJGTiX38GCZ2TmY9zQ1U7o1DwnWpHNRJRxArSN/xzLrbcSKy8InMyc+4A+VHf5pV0Pk8NdPV6++w== dependencies: - axios "0.24.0" + axios "1.6.1" bech32 "1.1.4" bignumber.js "9.0.1" buffer "6.0.3" @@ -2905,6 +2905,15 @@ axios@0.27.2, axios@^0.27.0, axios@^0.27.2: follow-redirects "^1.14.9" form-data "^4.0.0" +axios@1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.1.tgz#76550d644bf0a2d469a01f9244db6753208397d7" + integrity sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + axios@^0.21.1: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" @@ -2926,6 +2935,15 @@ axios@^0.26.0, axios@^0.26.1: dependencies: follow-redirects "^1.14.8" +axios@^1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2" + integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + b64-lite@^1.3.1, b64-lite@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/b64-lite/-/b64-lite-1.4.0.tgz#e62442de11f1f21c60e38b74f111ac0242283d3d" @@ -8225,10 +8243,10 @@ typescript-compiler@^1.4.1-2: resolved "https://registry.yarnpkg.com/typescript-compiler/-/typescript-compiler-1.4.1-2.tgz#ba4f7db22d91534a1929d90009dce161eb72fd3f" integrity sha512-EMopKmoAEJqA4XXRFGOb7eSBhmQMbBahW6P1Koayeatp0b4AW2q/bBqYWkpG7QVQc9HGQUiS4trx2ZHcnAaZUg== -typescript@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.2.tgz#00d1c7c1c46928c5845c1ee8d0cc2791031d4c43" - integrity sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ== +typescript@^4.9.3: + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== typescript@~4.4.4: version "4.4.4"