UNPKG

@intuweb3/sdk

Version:

INTU SDK - Modern blockchain interaction toolkit

214 lines 10.5 kB
import { createRandomMessage, createSeed, formTransaction, getMasterPublicKey, preRegister, getPolybaseKey, } from "./cryptography/index.js"; import { createVault, preRegisterStep, proposeTransaction, userCompleteVault, } from "./web3/signerfunctions.js"; import { getUserPreRegisterInfos, getUserSignature, getUserRegistrationAllInfos, } from "./web3/utils.js"; import { ethers } from "ethers"; import { hexToBytes } from "@noble/hashes/utils"; import { getPublicKey } from "nostr-tools/pure"; import { parseEther } from "viem"; import { createViemClientForTransaction, getVaultContract, } from "./web3/helper/index.js"; import { getProviderForChain } from "../tools/chainList.js"; import { getDataWithFallback, } from "./direct/index.js"; let getGraphEndpoint; (async () => { const constants = await import("../tools/constants.js"); getGraphEndpoint = constants.getGraphEndpoint; })(); export async function createIntuAccount(addressList, vaultName, rotationThreshold, transactionThreshold, adminThreshold, signer, returnHash = false) { const { seed } = await createSeed(); const { message } = await createRandomMessage(); let createVaultResult = await createVault(addressList, vaultName, rotationThreshold, transactionThreshold, adminThreshold, message, seed, signer, returnHash); return createVaultResult; } export async function createPolybaseKey(vaultAddress, signer, intuSignature) { let signature = ""; intuSignature ? (signature = intuSignature) : (signature = await getUserSignature(vaultAddress, signer)); return await getPolybaseKey(signature); } export async function preRegistration(vaultAddress, signer, intuSignature, returnHash) { let userAddress = await signer.getAddress(); const provider = signer.provider; const chainId = (await provider.getNetwork()).chainId; const indexerUrl = process.env.INDEXER_URL || process.env.REACT_APP_INDEXER_URL || getGraphEndpoint(chainId); console.log("🔍 preRegistration debug:"); console.log(" - chainId:", chainId); console.log(" - INTU_NETWORK env:", process.env.INTU_NETWORK); console.log(" - REACT_APP_INTU_NETWORK env:", process.env.REACT_APP_INTU_NETWORK); console.log(" - INDEXER_URL env:", process.env.INDEXER_URL); console.log(" - REACT_APP_INDEXER_URL env:", process.env.REACT_APP_INDEXER_URL); console.log(" - getGraphEndpoint result:", getGraphEndpoint(chainId)); console.log(" - final indexerUrl:", indexerUrl); const preRegCheck = await getDataWithFallback(() => getUserPreRegisterInfos(vaultAddress, userAddress, provider), provider, indexerUrl, 25); if (preRegCheck.registered) { console.log("user already preregistered : ", userAddress); return `User already preregistered : ${userAddress}`; } let signature; intuSignature ? (signature = intuSignature) : (signature = await getUserSignature(vaultAddress, signer)); const { encryptionKey, megaPublicKey, encMegaSecretKey } = await preRegister(signature); let dbKey = await getPolybaseKey(signature); let sk = dbKey.key; let pkfinal = getPublicKey(hexToBytes(String(sk))); let rh = returnHash || false; return await preRegisterStep(vaultAddress, encryptionKey, megaPublicKey, encMegaSecretKey, pkfinal, signer, rh); } export async function completeVault(vaultAddress, signer, returnHash) { const retryWithDelay = async (fn, retries = 5, delay = 1000) => { try { return await fn(); } catch (error) { console.log(`Attempt failed, retries left: ${retries}. Error:`, error?.message || error); if (retries === 0) throw error; await new Promise((resolve) => setTimeout(resolve, delay)); return retryWithDelay(fn, retries - 1, delay); } }; return retryWithDelay(async () => { let mpk = ""; let rh = returnHash || false; const vaultContract = await getVaultContract(vaultAddress, signer.provider); const { users, completed, createdDate } = await retryWithDelay(() => vaultContract.vaultInfos(), 5, 2000); if (completed) { return "Vault is already completed."; } if (users.length >= 3) { const finalUsers = [users[0], users[1], users[2]]; const userAddress = await signer.getAddress(); try { const userRegistrationAll = await getUserRegistrationAllInfos(vaultAddress, signer.provider); if (!userRegistrationAll || userRegistrationAll.length === 0) { console.log("❌ [CompleteVault] No user registration data available yet, retrying..."); throw new Error("No user registration data available yet"); } const hasAnyData = userRegistrationAll.some((data) => data !== null); if (!hasAnyData) { console.log("❌ [CompleteVault] No user registration data has content yet, retrying..."); throw new Error("No user registration data has content yet"); } const userIndex = users.findIndex((address) => address.toLowerCase() === userAddress.toLowerCase()); if (userIndex === -1) { throw new Error("User not found in vault members"); } if (!userRegistrationAll[0] || !userRegistrationAll[1] || !userRegistrationAll[2]) { console.log("⏳ [CompleteVault] Registration data not available for all users, retrying..."); throw new Error("Registration data not available for all users"); } if (!userRegistrationAll[userIndex]) { console.log(`❌ [CompleteVault] User registration data not yet available for user ${userIndex}, retrying...`); throw new Error("User registration data not yet available"); } const step3Crypto = userRegistrationAll[userIndex].step3Crypto; if (!step3Crypto) { console.log("❌ [CompleteVault] Step 3 crypto data not yet available, retrying..."); throw new Error("Step 3 crypto data not yet available"); } try { let step3Result = JSON.parse(atob(step3Crypto)); if (!Array.isArray(step3Result) || step3Result.length < 5) { throw new Error(`Invalid step3Result format: ${JSON.stringify(step3Result)}`); } mpk = await getMasterPublicKey(step3Result[4]); const MPK = "0x" + mpk; return await userCompleteVault(vaultAddress, finalUsers, MPK, signer, rh); } catch (parseError) { console.error("❌ [CompleteVault] Error parsing step3Crypto:", parseError); throw parseError; } } catch (error) { throw error; } } return "Not enough users or data not available"; }); } export async function submitTransaction(to, value, chainId, nonce, data, gasPrice, gas, vaultAddress, signer, notes = "n/a", returnHash = false, sendingProvider) { let date = new Date(); let provider; let client; let signerAddress; if (!sendingProvider) { provider = await getProviderForChain(chainId); } else { if (typeof sendingProvider === "string") { provider = new ethers.providers.StaticJsonRpcProvider(sendingProvider); } else { provider = sendingProvider; } } client = await createViemClientForTransaction(provider); signerAddress = await signer.getAddress(); let decimal = 18; let finalGasPrice; let gasInfo = await provider.getFeeData(); if (gasPrice === undefined || gasPrice === null || gasPrice === "") { if (gasInfo.gasPrice) { finalGasPrice = gasInfo.gasPrice.mul(105).div(100); } else { throw new Error("Unable to determine gas price"); } } else { finalGasPrice = ethers.BigNumber.from(gasPrice); } let gE = null; const vc = await getVaultContract(vaultAddress, signer.provider); const gvc = await vc.vaultInfos(); let masterPublicKey = gvc.masterPublicKey; try { if (data) { gE = await client.estimateGas({ account: masterPublicKey, to: to, value: parseEther(String(value)), data: data, }); } else { gE = await client.estimateGas({ account: masterPublicKey, to: to, value: parseEther(String(value)), }); } } catch (e) { console.warn(`You are likely experiencing an error because the account ${masterPublicKey} doesn't have enough funds to cover the gas+value being requested to transfer on ${chainId}`); console.log(e); return; } let finalGasLimit; if (gas === undefined || gas === null || gas === "") { if (gE) { finalGasLimit = ethers.BigNumber.from(gE).mul(105).div(100); } else { throw new Error("Unable to determine gas limit"); } } else { finalGasLimit = ethers.BigNumber.from(gas); } const formTxResponse = await formTransaction(to, String(value), String(chainId), String(nonce), String(data), finalGasPrice.toString(), finalGasLimit.toString(), String(decimal)); const response = await proposeTransaction(vaultAddress, formTxResponse, signer, notes, returnHash); let date2 = new Date(); if (process.env.DEBUG) { console.log("SUBMIT TX TIME : ", date2.getTime() - date.getTime()); } return response; } export { getVaults, getVaultSingle, getVaultsWithoutTransactions, getVaultSingleWithDEOA, getAllTransactions, getTransaction, getTransactionLean, signTx, combineSignedTx, getProposal, getProposedUser, getUserCompletedRotationRegistrationCount, getUserPreRegisterInfos, getUserSignature, getUtilsParams, getUserRegistrationAllInfos, getRegistrationStep3InfosDB, getRegistrationReshareStep3InfosDB, } from "./index.js"; //# sourceMappingURL=index.native.js.map