UNPKG

@myria/airdrop-js

Version:

Airdrop in L1 with claim based approach

104 lines 9.81 kB
"use strict"; /** * Collection of wrapper functions which include single functions in core to simplify consumers's integration like plug (config in) and play * @module Transaction/Wrapper */ Object.defineProperty(exports, "__esModule", { value: true }); exports.approveWhitelistAndAllowance = exports.saveMerkleTreeByOwner = void 0; const ErrorCodeType_1 = require("../type/ErrorCodeType"); const core_1 = require("./core"); const internalUse_1 = require("./internalUse"); const validation_1 = require("./validation"); /** * Wrapper function: Airdrop's owner approve whitelist to save on-chain include both setMerkleRoot and saveSnapshot * * @param {Account} account - The Account represent as sender @see {@link https://ethereum.org/en/glossary/#account|Account's Ethereum}. * @param {string} merkleRoot - The generated merkleRoot from whitelist @see {@link generateMerkleTreeInfoERC20ForWhitelist|Generate merkleRoot} * @param {string} snapshotUri - The generated snapshotUri from whitelist @see {@link generateMerkleTreeInfoERC20ForWhitelist|Generate snapshotUri} * @param {ThirdwebContract} airdropContract - The airdrop Thirdweb contract. * @param {Address} tokenAddress - The token address to claim. * @param {RetryOptions} retryOptions - The configuration on retry * @param {ExtraGasOptions} extraGasOptions - The extra gas options bidding for your transaction to be included in the next block. * @returns {Promise<SaveMerkleTreeResult>} A promise that resolves to the confirmed transaction hashes accordingly. */ async function saveMerkleTreeByOwner(account, merkleRoot, snapshotUri, airdropContract, tokenAddress, retryOptions = {}, extraGasOptions = {}) { const startTime = (0, internalUse_1.logFunctionTrackStartTime)(saveMerkleTreeByOwner.name); // Check to skip approve allowance to reduce our cost const shouldSkipSubmitting = await (0, validation_1.isAlreadySubmittedOnchain)(airdropContract, tokenAddress, merkleRoot); if (shouldSkipSubmitting) { (0, internalUse_1.logFunctionDuration)(saveMerkleTreeByOwner.name, startTime); return { snapshotResult: ErrorCodeType_1.ALREADY_SUBMITTED_SKIP_TRANSACTION, merkleRootResult: ErrorCodeType_1.ALREADY_SUBMITTED_SKIP_TRANSACTION, }; } // Save snapshot const { transactionHash: snapshotTransactionHash } = await (0, core_1.saveSnapshotByOwner)(account, airdropContract, merkleRoot, snapshotUri, retryOptions, extraGasOptions); const snapshotResult = { transactionHash: snapshotTransactionHash }; // Set MerkleRoot const { transactionHash: merkleRootTransactionHash } = await (0, core_1.saveMerkleRootByOwner)(account, airdropContract, tokenAddress, merkleRoot, retryOptions, extraGasOptions); const merkleRootResult = { transactionHash: merkleRootTransactionHash }; (0, internalUse_1.logFunctionDuration)(saveMerkleTreeByOwner.name, startTime); // In case of resubmit with the same data. The transaction hash will be empty return { snapshotResult, merkleRootResult, }; } exports.saveMerkleTreeByOwner = saveMerkleTreeByOwner; /** * Wrapper function: Owner approve the whitelist on behalf of Airdrop's contract owner and approve allowance on behalf of Token's contract owner. * * @param {Account} account - The Account represent as sender @see {@link https://ethereum.org/en/glossary/#account|Account's Ethereum}. * @param {string} merkleRoot - The generated merkleRoot from whitelist @see {@link generateMerkleTreeInfoERC20ForWhitelist|Generate merkleRoot} * @param {string} snapshotUri - The generated snapshotUri from whitelist @see {@link generateMerkleTreeInfoERC20ForWhitelist|Generate snapshotUri} * @param {ThirdwebContract} airdropContract - The airdrop Thirdweb contract. * @param {ThirdwebContract} tokenContract - The token Thirdweb contract to airdrop * @param {number} totalAmount - The total airdrop amount in ether format. * @param {RetryOptions} retryOptions - The configuration on retry * @param {ExtraGasOptions} extraGasOptions - The extra gas options bidding for your transaction to be included in the next block. * @returns {Promise<ApproveWhitelistAndAllowanceResult>} A promise that resolves to the confirmed transaction hashes accordingly. * @throws An error if the totalAmount <= 0. */ async function approveWhitelistAndAllowance(account, merkleRoot, snapshotUri, airdropContract, tokenContract, totalAmount, retryOptions = {}, extraGasOptions = {}) { if (totalAmount <= 0) { throw Error('totalAmount must be greater than 0'); } const ownerAddress = await (0, core_1.getOwnerOfContract)(airdropContract); if (account.address.toLowerCase() !== ownerAddress.toLowerCase()) { throw Error('account must belong to airdropContract owner'); } const startTime = (0, internalUse_1.logFunctionTrackStartTime)(approveWhitelistAndAllowance.name); // Save MerkleTree on-chain const saveMerkleTreeResult = await saveMerkleTreeByOwner(account, merkleRoot, snapshotUri, airdropContract, tokenContract.address, retryOptions, extraGasOptions); // Approve Allowance // Check to skip approve allowance to reduce our cost const shouldSkipApproveSpender = await (0, validation_1.isAlreadyApprovedAllowanceOnchain)(account.address, airdropContract.address, tokenContract, totalAmount); if (shouldSkipApproveSpender) { (0, internalUse_1.logFunctionDuration)(approveWhitelistAndAllowance.name, startTime); return { ...saveMerkleTreeResult, approveAllowanceResult: ErrorCodeType_1.ALREADY_SUBMITTED_SKIP_TRANSACTION, }; } let approveAllowanceResult; try { const { transactionHash } = await (0, core_1.approveAirdropAsSpender)(airdropContract.address, totalAmount, account, tokenContract); approveAllowanceResult = { transactionHash, }; } catch (error) { approveAllowanceResult = { ...ErrorCodeType_1.GENERIC_ERROR, errorMessage: error.message, }; } (0, internalUse_1.logFunctionDuration)(approveWhitelistAndAllowance.name, startTime); return { ...saveMerkleTreeResult, approveAllowanceResult: approveAllowanceResult, }; } exports.approveWhitelistAndAllowance = approveWhitelistAndAllowance; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3JhcHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90cmFuc2FjdGlvbi93cmFwcGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7OztBQVdILHlEQUcrQjtBQUMvQixpQ0FPZ0I7QUFDaEIsK0NBQStFO0FBQy9FLDZDQUdzQjtBQUV0Qjs7Ozs7Ozs7Ozs7R0FXRztBQUNJLEtBQUssVUFBVSxxQkFBcUIsQ0FDdkMsT0FBZ0IsRUFDaEIsVUFBa0IsRUFDbEIsV0FBbUIsRUFDbkIsZUFBaUMsRUFDakMsWUFBb0IsRUFDcEIsZUFBNkIsRUFBRSxFQUMvQixrQkFBbUMsRUFBRTtJQUVyQyxNQUFNLFNBQVMsR0FBRyxJQUFBLHVDQUF5QixFQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hFLHFEQUFxRDtJQUNyRCxNQUFNLG9CQUFvQixHQUFHLE1BQU0sSUFBQSxzQ0FBeUIsRUFDeEQsZUFBZSxFQUNmLFlBQVksRUFDWixVQUFVLENBQ2IsQ0FBQztJQUNGLElBQUksb0JBQW9CLEVBQUUsQ0FBQztRQUN2QixJQUFBLGlDQUFtQixFQUFDLHFCQUFxQixDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUMzRCxPQUFPO1lBQ0gsY0FBYyxFQUFFLGtEQUFrQztZQUNsRCxnQkFBZ0IsRUFBRSxrREFBa0M7U0FDdkQsQ0FBQztJQUNOLENBQUM7SUFFRCxnQkFBZ0I7SUFDaEIsTUFBTSxFQUFFLGVBQWUsRUFBRSx1QkFBdUIsRUFBRSxHQUM5QyxNQUFNLElBQUEsMEJBQW1CLEVBQ3JCLE9BQU8sRUFDUCxlQUFlLEVBQ2YsVUFBVSxFQUNWLFdBQVcsRUFDWCxZQUFZLEVBQ1osZUFBZSxDQUNsQixDQUFDO0lBQ04sTUFBTSxjQUFjLEdBQUcsRUFBRSxlQUFlLEVBQUUsdUJBQXVCLEVBQUUsQ0FBQztJQUVwRSxpQkFBaUI7SUFDakIsTUFBTSxFQUFFLGVBQWUsRUFBRSx5QkFBeUIsRUFBRSxHQUNo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