UNPKG

@samudai_xyz/web3-sdk

Version:

## All in one web3 integrations for Samudai

667 lines (666 loc) 30.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Gnosis = void 0; const ethers_1 = require("ethers"); const safe_core_sdk_1 = require("@gnosis.pm/safe-core-sdk"); const protocol_kit_1 = __importStar(require("@safe-global/protocol-kit")); const axios_1 = __importDefault(require("axios")); const networks_1 = require("../utils/networks"); const api_kit_1 = __importDefault(require("@safe-global/api-kit")); const helpers_1 = require("../lib/helpers"); class Gnosis { //Constructor constructor(provider, chainId) { this.safeAddress = ''; this.provider = null; this.etherAdapter = null; this.txServiceUrl = ''; // private generateBatchTransaction = ( // value: string, // receiverAddresses: string[], // tokenAddress?: string // ): MetaTransactionData[] => { // const transactions: MetaTransactionData[] = [] // const receiverValue: number = parseInt(value) / receiverAddresses.length // if (tokenAddress) { // receiverAddresses.map((receiverAddress) => { // const encodedData = encodeData( // ethers.utils.getAddress(receiverAddress), // receiverValue.toString() // ) // transactions.push({ // to: ethers.utils.getAddress(tokenAddress), // value: '0', // data: encodedData, // operation: 0, // }) // }) // } else { // receiverAddresses.map((receiverAddress) => { // transactions.push({ // to: receiverAddress, // value: receiverValue.toString(), // data: '0x', // operation: 0, // }) // }) // } // return transactions // } this.generateCustomERC20Transaction = (receiverAddress, customERC20Token) => { const transactions = []; customERC20Token.map((token) => { if (token.tokenAddress) { const encodedData = (0, helpers_1.encodeData)(ethers_1.ethers.utils.getAddress(receiverAddress), token.value); transactions.push({ to: ethers_1.ethers.utils.getAddress(token.tokenAddress), value: '0', data: encodedData, operation: 0, }); } else { transactions.push({ to: receiverAddress, value: token.value, data: '0x', operation: 0, }); } }); return transactions; }; this.createSingleGnosisTx = async (receiverAddress, value, safeAddress, senderAddress, tokenAddress) => { try { this.safeAddress = ethers_1.ethers.utils.getAddress(safeAddress); if (this.provider) { const safeOwner = await this.provider.getSigner(0); let finalValue = value; this.etherAdapter = new protocol_kit_1.EthersAdapter({ ethers: ethers_1.ethers, signerOrProvider: safeOwner, }); const safeService = new api_kit_1.default({ txServiceUrl: this.txServiceUrl, ethAdapter: this.etherAdapter, }); const safeSDK = await protocol_kit_1.default.create({ ethAdapter: this.etherAdapter, safeAddress: this.safeAddress, }); const nonce = await safeService.getNextNonce(this.safeAddress); let encodedCallData = '0x'; if (tokenAddress) { const decimals = await (0, helpers_1.getDecimalsForToken)(this.chainId, tokenAddress); finalValue = ethers_1.ethers.utils.parseUnits(value, decimals).toString(); } else { finalValue = ethers_1.ethers.utils.parseEther(value).toString(); } if (tokenAddress) { encodedCallData = (0, helpers_1.encodeData)(ethers_1.ethers.utils.getAddress(receiverAddress), finalValue); } const to = tokenAddress ? tokenAddress : receiverAddress; const tokenValue = tokenAddress ? '0' : finalValue; const safeTransactionData = { to: ethers_1.ethers.utils.getAddress(to), data: encodedCallData, value: tokenValue, operation: 0, nonce: nonce, }; const safeTransaction = await safeSDK.createTransaction({ safeTransactionData, }); const safeTxHash = await safeSDK.getTransactionHash(safeTransaction); const senderSignature = await safeSDK.signTransactionHash(safeTxHash); const result = await safeService.proposeTransaction({ safeAddress: this.safeAddress, safeTransactionData: safeTransaction.data, safeTxHash, senderAddress: ethers_1.ethers.utils.getAddress(senderAddress), senderSignature: senderSignature.data, origin: 'Samudai Platform', }); const data = { safeTxHash: safeTxHash, proposedSafeTx: result, }; return data; } else { throw new Error('Provider not found'); } } catch (err) { throw err; } }; this.createBatchTx = async (transactions, safeAddress, senderAddress) => { try { this.safeAddress = ethers_1.ethers.utils.getAddress(safeAddress); if (this.provider) { const safeOwner = await this.provider.getSigner(0); this.etherAdapter = new protocol_kit_1.EthersAdapter({ ethers: ethers_1.ethers, signerOrProvider: safeOwner, }); const safeService = new api_kit_1.default({ txServiceUrl: this.txServiceUrl, ethAdapter: this.etherAdapter, }); const safeSDK = await protocol_kit_1.default.create({ ethAdapter: this.etherAdapter, safeAddress: this.safeAddress, }); const nonce = await safeService.getNextNonce(this.safeAddress); const options = { nonce: nonce, }; const safeTransactionData = []; await Promise.all(transactions.map(async (tx) => { if ((tx === null || tx === void 0 ? void 0 : tx.tokenAddress) === '') { const safeTransactionDataItem = { to: '', data: '', value: '', }; safeTransactionDataItem.to = ethers_1.ethers.utils.getAddress(tx.to); safeTransactionDataItem.data = '0x'; safeTransactionDataItem.value = ethers_1.ethers.utils .parseEther(tx.value) .toString(); safeTransactionData.push(safeTransactionDataItem); } else { const safeTransactionDataItem = { to: '', data: '', value: '', }; const decimals = await (0, helpers_1.getDecimalsForToken)(this.chainId, tx === null || tx === void 0 ? void 0 : tx.tokenAddress); const val = ethers_1.ethers.utils .parseUnits(tx.value, decimals) .toString(); safeTransactionDataItem.value = '0'; const encodedCallData = (0, helpers_1.encodeData)(ethers_1.ethers.utils.getAddress(tx.to), val); safeTransactionDataItem.to = ethers_1.ethers.utils.getAddress(tx === null || tx === void 0 ? void 0 : tx.tokenAddress); safeTransactionDataItem.data = encodedCallData; safeTransactionData.push(safeTransactionDataItem); } })); const safeTransaction = await safeSDK.createTransaction({ safeTransactionData: safeTransactionData, onlyCalls: true, options, }); const safeTxHash = await safeSDK.getTransactionHash(safeTransaction); const senderSignature = await safeSDK.signTransactionHash(safeTxHash); const result = await safeService.proposeTransaction({ safeAddress: this.safeAddress, safeTransactionData: safeTransaction.data, safeTxHash, senderAddress: ethers_1.ethers.utils.getAddress(senderAddress), senderSignature: senderSignature.data, origin: 'Samudai Platform', }); const data = { safeTxHash: safeTxHash, proposedSafeTx: result, }; return data; } else { throw new Error('Provider not found'); } } catch (error) { throw error; } }; this.getPendingTransactions = async (safeAddress) => { try { if (this.provider) { const safeOwner = await this.provider.getSigner(0); this.etherAdapter = new protocol_kit_1.EthersAdapter({ ethers: ethers_1.ethers, signerOrProvider: safeOwner, }); const safeService = new api_kit_1.default({ txServiceUrl: this.txServiceUrl, ethAdapter: this.etherAdapter, }); const pendingTxs = await safeService.getPendingTransactions(ethers_1.ethers.utils.getAddress(safeAddress)); return pendingTxs; } else { throw new Error('Provider not found'); } } catch (err) { throw err; } }; /** * Function to return all safe transactions executed * @param safeAddress string - The address of the Gnosis Safe * @returns SafeTransactions - The response from the Gnosis Safe */ this.getExecutedTransactions = async (safeAddress) => { try { const res = await axios_1.default.get(`${this.txServiceUrl}/api/v1/safes/${safeAddress}/multisig-transactions/?executed=true`); return res.data; } catch (err) { throw err; } }; this.getRecentTransactions = async (safeAddress) => { try { const res = await axios_1.default.get(`${this.txServiceUrl}/api/v1/safes/${safeAddress}/all-transactions/?limit=40&executed=false&queued=true&trusted=true`); return res.data; } catch (err) { throw err; } }; this.getTransactionDetails = async (safeTxHash) => { try { if (this.provider) { const safeOwner = await this.provider.getSigner(0); this.etherAdapter = new protocol_kit_1.EthersAdapter({ ethers: ethers_1.ethers, signerOrProvider: safeOwner, }); const safeService = new api_kit_1.default({ txServiceUrl: this.txServiceUrl, ethAdapter: this.etherAdapter, }); const tx = await safeService.getTransaction(safeTxHash); const safeOwners = await safeService.getSafeInfo(this.safeAddress); const data = { safeMultisigTransactionResponse: tx, confirmation: safeOwners.threshold, }; return data; } else { throw new Error('Provider not found'); } } catch (err) { throw err; } }; this.isTransactionOwner = async (safeAddress) => { try { if (this.provider) { let isOwner = false; const safeOwner = await this.provider.getSigner(0); const userAddress = await safeOwner.getAddress(); this.etherAdapter = new protocol_kit_1.EthersAdapter({ ethers: ethers_1.ethers, signerOrProvider: safeOwner, }); const safeService = new api_kit_1.default({ txServiceUrl: this.txServiceUrl, ethAdapter: this.etherAdapter, }); const safeInfo = await safeService.getSafeInfo(safeAddress); safeInfo.owners.find((owner) => { if (owner === userAddress) { isOwner = true; } else { isOwner = false; } }); return isOwner; } else { throw new Error('Provider not found'); } } catch (err) { throw err; } }; this.isTransactionExecutable = async (safeTxHash, safeAddress) => { try { if (this.provider) { let isOwner = false; let isExecutable = false; let isConfirmation = false; const safeOwner = await this.provider.getSigner(0); const userAddress = await safeOwner.getAddress(); this.etherAdapter = new protocol_kit_1.EthersAdapter({ ethers: ethers_1.ethers, signerOrProvider: safeOwner, }); const safeService = new api_kit_1.default({ txServiceUrl: this.txServiceUrl, ethAdapter: this.etherAdapter, }); const transaction = await safeService.getTransaction(safeTxHash); const safeInfo = await safeService.getSafeInfo(safeAddress); const isSafeOwner = safeInfo.owners.find((owner) => owner === ethers_1.ethers.utils.getAddress(userAddress)); if (isSafeOwner) { isOwner = true; } else { isOwner = false; } if (isOwner) { const confirmation = transaction.confirmations.find((confirmation) => confirmation.owner === ethers_1.ethers.utils.getAddress(userAddress)); if (confirmation) { isConfirmation = false; } else { isConfirmation = true; } if (transaction.confirmations) { if (transaction.confirmations.length >= safeInfo.threshold) { isExecutable = true; } else { isExecutable = false; } } return { isOwner, isConfirmation, isExecutable, }; } else { return { isOwner, }; } } else { throw new Error('Provider not found'); } } catch (err) { throw err; } }; this.confirmTransaction = async (safeTxHash, safeAddress) => { try { if (this.provider) { this.safeAddress = ethers_1.ethers.utils.getAddress(safeAddress); const safeOwner = await this.provider.getSigner(0); this.etherAdapter = new protocol_kit_1.EthersAdapter({ ethers: ethers_1.ethers, signerOrProvider: safeOwner, }); const safeService = new api_kit_1.default({ txServiceUrl: this.txServiceUrl, ethAdapter: this.etherAdapter, }); const safeSDK = await protocol_kit_1.default.create({ ethAdapter: this.etherAdapter, safeAddress: this.safeAddress, }); const signature = await safeSDK.signTransactionHash(safeTxHash); const result = await safeService.confirmTransaction(safeTxHash, signature.data); return result; } else { throw new Error('Provider not found'); } } catch (err) { throw err; } }; this.rejectTransaction = async (safeAddress, nonce, senderAddress) => { try { if (this.provider) { this.safeAddress = ethers_1.ethers.utils.getAddress(safeAddress); const safeOwner = await this.provider.getSigner(0); this.etherAdapter = new protocol_kit_1.EthersAdapter({ ethers: ethers_1.ethers, signerOrProvider: safeOwner, }); const safeService = new api_kit_1.default({ txServiceUrl: this.txServiceUrl, ethAdapter: this.etherAdapter, }); const safeSDK = await protocol_kit_1.default.create({ ethAdapter: this.etherAdapter, safeAddress: this.safeAddress, }); const safeTransaction = await safeSDK.createRejectionTransaction(nonce); const safeTxHash = await safeSDK.getTransactionHash(safeTransaction); const senderSignature = await safeSDK.signTransactionHash(safeTxHash); const result = await safeService.proposeTransaction({ safeAddress: this.safeAddress, safeTransactionData: safeTransaction.data, safeTxHash, senderAddress: ethers_1.ethers.utils.getAddress(senderAddress), senderSignature: senderSignature.data, origin: 'Samudai Platform', }); const data = { safeTxHash: safeTxHash, proposedSafeTx: result, }; return data; } else { throw new Error('Provider not found'); } } catch (error) { throw error; } }; this.executeTransaction = async (safeTxHash, safeAddress) => { try { if (this.provider) { this.safeAddress = ethers_1.ethers.utils.getAddress(safeAddress); const safeOwner = await this.provider.getSigner(0); this.etherAdapter = new protocol_kit_1.EthersAdapter({ ethers: ethers_1.ethers, signerOrProvider: safeOwner, }); const safeService = new api_kit_1.default({ txServiceUrl: this.txServiceUrl, ethAdapter: this.etherAdapter, }); const safeSDK = await protocol_kit_1.default.create({ ethAdapter: this.etherAdapter, safeAddress: this.safeAddress, }); const transaction = await safeService.getTransaction(safeTxHash); const safeTransactionData = { to: transaction.to, value: transaction.value, data: transaction.data || '0x', operation: transaction.operation, safeTxGas: transaction.safeTxGas.toString(), baseGas: transaction.baseGas.toString(), gasPrice: parseInt(transaction.gasPrice).toString(), gasToken: transaction.gasToken, refundReceiver: transaction.refundReceiver, nonce: transaction.nonce, }; const safeTransaction = await safeSDK.createTransaction({ safeTransactionData, }); transaction.confirmations.forEach((confirmation) => { const signature = new safe_core_sdk_1.EthSignSignature(confirmation.owner, confirmation.signature); safeTransaction.addSignature(signature); }); const executeTxResponse = await safeSDK.executeTransaction(safeTransaction); const receipt = executeTxResponse.transactionResponse && (await executeTxResponse.transactionResponse.wait()); return receipt; } else { throw new Error('Provider not found'); } } catch (err) { throw err; } }; this.getSafeOwners = async (safeAddress) => { try { const owners = []; const result = await axios_1.default.get(`${this.txServiceUrl}/api/v1/safes/${safeAddress}/`); const safeOwners = result.data.owners; for (const owner of safeOwners) { //const address = (await this.provider?.lookupAddress(owner)) || owner owners.push(owner); } return owners; } catch (err) { return null; } }; this.connectGnosis = async (userAddress) => { try { const UserSafes = []; const result = await axios_1.default.get(`${this.txServiceUrl}/api/v1/owners/${userAddress}/safes/`); const userSafes = result.data.safes; for (const userSafe of userSafes) { const owners = await this.getSafeOwners(userSafe); UserSafes.push({ safeAddress: userSafe, owners: owners, }); } return UserSafes; } catch (err) { throw err; } }; // Reminder to change the api url before pushing to dev this.getSafeBalance = async (safeAddress) => { try { const result = await axios_1.default.get(`${this.txServiceUrl}/api/v1/safes/${safeAddress}/balances/usd/?trusted=false&exclude_spam=false` // `https://safe-transaction-goerli.safe.global/api/v1/safes/0x6744fC3A5A9CAAeC22c939Bb0737679b768C5e4c/balances/usd/?trusted=false&exclude_spam=false` ); const balance = result.data; return balance; } catch (err) { throw err; } }; // Reminder to change the api url before pushing to dev this.getSafeBalanceinUSD = async (safeAddress) => { try { const result = await axios_1.default.get(`https://api.portals.fi/v2/account?owner=${safeAddress}&networks=ethereum`); const balance = result.data; return balance; } catch (err) { throw err; } }; this.verifySafe = async (safeAddress) => { try { const result = await axios_1.default.get(`${this.txServiceUrl}/api/v1/safes/${safeAddress}/`); if (result.status === 200) { return true; } else { return false; } } catch (err) { throw err; } }; this.customERC20Transfer = async (safeAddress, receiverAddress, senderAddress, customERC20Token) => { try { this.safeAddress = ethers_1.ethers.utils.getAddress(safeAddress); if (this.provider) { const safeOwner = await this.provider.getSigner(0); this.etherAdapter = new protocol_kit_1.EthersAdapter({ ethers: ethers_1.ethers, signerOrProvider: safeOwner, }); const safeService = new api_kit_1.default({ txServiceUrl: this.txServiceUrl, ethAdapter: this.etherAdapter, }); const safeSDK = await protocol_kit_1.default.create({ ethAdapter: this.etherAdapter, safeAddress: this.safeAddress, }); const nonce = await safeService.getNextNonce(this.safeAddress); const safeTransactionData = this.generateCustomERC20Transaction(receiverAddress, customERC20Token); const options = { nonce, // Optional }; const safeTransaction = await safeSDK.createTransaction({ safeTransactionData, options, }); const safeTxHash = await safeSDK.getTransactionHash(safeTransaction); const senderSignature = await safeSDK.signTransactionHash(safeTxHash); const result = await safeService.proposeTransaction({ safeAddress: this.safeAddress, safeTransactionData: safeTransaction.data, safeTxHash, senderAddress: ethers_1.ethers.utils.getAddress(senderAddress), senderSignature: senderSignature.data, origin: 'Samudai Platform', }); const data = { safeTxHash: safeTxHash, proposedSafeTx: result, }; return data; } else { throw new Error('Provider not found'); } } catch (err) { throw err; } }; this.provider = provider; this.chainId = chainId; networks_1.Networks.forEach((network) => { if (network.chainId === chainId) { this.txServiceUrl = network.url; } }); } } exports.Gnosis = Gnosis;