diff --git a/README.md b/README.md index 67bf86e7..5515cb6e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Lighthouse +# Lighthouse Lighthouse is a permanent decentralized file storage protocol that allows the ability to pay once and store forever. While traditionally, users need to repeatedly keep track and pay for their storage after every fixed amount of time, Lighthouse manages this for them and makes sure that user files are stored forever. The aim is to move users from a rent-based cost model where they are renting their own files on cloud storage to a permanent ownership model. It is built on top of IPFS, Filecoin, and Polygon. It uses the existing miner network and storage capacity of the filecoin network. diff --git a/package-lock.json b/package-lock.json index 733cb985..80297dd2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@lighthouse-web3/sdk", - "version": "0.4.3", + "version": "0.4.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@lighthouse-web3/sdk", - "version": "0.4.3", + "version": "0.4.4", "license": "MIT", "dependencies": { "@lighthouse-web3/kavach": "^0.1.9", diff --git a/package.json b/package.json index 1ce8c350..eda3d79b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lighthouse-web3/sdk", - "version": "0.4.3", + "version": "0.4.4", "description": "NPM package and CLI tool to interact with lighthouse protocol", "main": "./dist/Lighthouse/index.js", "types": "./dist/Lighthouse/index.d.ts", diff --git a/src/Commands/index.ts b/src/Commands/index.ts index a000a908..22092f59 100644 --- a/src/Commands/index.ts +++ b/src/Commands/index.ts @@ -72,7 +72,7 @@ Command.prototype.helpInformation = function (context: any) { } widgets.addHelpText('before', 'Welcome to lighthouse-web3') -widgets.version('0.4.3') +widgets.version('0.4.4') widgets .command('wallet') diff --git a/src/Commands/podsi.ts b/src/Commands/podsi.ts deleted file mode 100644 index f0e55400..00000000 --- a/src/Commands/podsi.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { green, red, bold, yellow } from 'kleur' -import { isCID } from '../Lighthouse/utils/util' -import getPodsi from '../Lighthouse/podsi' - -export default async function (cid: any, options: any) { - if (JSON.stringify(cid) === '{}') { - options.help() - } else { - try { - if (!isCID(cid)) { - throw new Error('Invalid CID') - } - const { data } = await getPodsi(cid) - console.log(bold().cyan('Piece Info:')) - console.log(green('Piece CID:'), data.pieceCID) - - console.log('\n' + bold().cyan('Proof Data:')) - - console.log('\n' + bold().cyan('Inclusion Proof:')) - console.log( - green('Proof Index:'), - data.dealInfo[0].proof.inclusionProof.proofIndex.index - ) - console.log(green('Proof Paths:')) - data.dealInfo[0].proof.inclusionProof.proofIndex.path.forEach((path) => { - console.log(yellow(' -'), path) - }) - - console.log('\n' + bold().cyan('Proof Subtree:')) - console.log( - green('Index:'), - data.dealInfo[0].proof.inclusionProof.proofSubtree.index - ) - console.log(green('Paths:')) - data.dealInfo[0].proof.inclusionProof.proofSubtree.path.forEach( - (path) => { - console.log(yellow(' -'), path) - } - ) - - console.log('\n' + bold().cyan('Deal Info:')) - data.dealInfo.forEach((deal) => { - console.log(green('Deal ID:'), deal.dealId) - console.log(green('Storage Provider:'), deal.storageProvider) - }) - } catch (error: any) { - console.log(red(error.message)) - process.exit(0) - } - } -} diff --git a/src/Lighthouse/index.ts b/src/Lighthouse/index.ts index 1edaa211..1e2e1b8c 100644 --- a/src/Lighthouse/index.ts +++ b/src/Lighthouse/index.ts @@ -7,12 +7,6 @@ import getFileInfo from './getFileInfo' import createWallet from './createWallet' import deleteFile from './deleteFile' -// Pay per deal -import fund from './payPerDeal/fund' -import getPrice from './payPerDeal/getPrice' -import oneTimeAuth from './payPerDeal/oneTimeAuth' - -// Encryption import shareFile from './encryption/shareFile' import getAuthMessage from './encryption/getAuthMessage' import revokeFileAccess from './encryption/revokeFileAccess' @@ -20,27 +14,20 @@ import fetchEncryptionKey from './encryption/fetchEncryptionKey' import applyAccessCondition from './encryption/applyAccessCondition' import getAccessConditions from './encryption/getAccessConditions' -// Upload import upload from './upload/files' import uploadText from './upload/text' import uploadBuffer from './upload/buffer' +import uploadCAR from './upload/car' import decryptFile from './uploadEncrypted/decrypt' import uploadEncrypted from './uploadEncrypted/encrypt/file' import textUploadEncrypted from './uploadEncrypted/encrypt/text' -// IPNS import generateKey from './ipns/generateKey' import publishRecord from './ipns/publishRecord' import getAllKeys from './ipns/getAllKeys' import removeKey from './ipns/removeKey' -//PODSI -import posdi from './podsi' - export { - fund, - getPrice, - oneTimeAuth, getQuote, getApiKey, getBalance, @@ -57,6 +44,7 @@ export { upload, uploadText, uploadBuffer, + uploadCAR, uploadEncrypted, textUploadEncrypted, decryptFile, @@ -64,14 +52,10 @@ export { publishRecord, getAllKeys, removeKey, - posdi, deleteFile, } export default { - fund, - getPrice, - oneTimeAuth, getQuote, getApiKey, getBalance, @@ -88,6 +72,7 @@ export default { upload, uploadText, uploadBuffer, + uploadCAR, uploadEncrypted, textUploadEncrypted, decryptFile, @@ -95,6 +80,5 @@ export default { publishRecord, getAllKeys, removeKey, - posdi, deleteFile, } diff --git a/src/Lighthouse/payPerDeal/fund/abi/erc20.ts b/src/Lighthouse/payPerDeal/fund/abi/erc20.ts deleted file mode 100644 index dcc20b94..00000000 --- a/src/Lighthouse/payPerDeal/fund/abi/erc20.ts +++ /dev/null @@ -1,222 +0,0 @@ -export default [ - { - constant: true, - inputs: [], - name: 'name', - outputs: [ - { - name: '', - type: 'string', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_spender', - type: 'address', - }, - { - name: '_value', - type: 'uint256', - }, - ], - name: 'approve', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'totalSupply', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_from', - type: 'address', - }, - { - name: '_to', - type: 'address', - }, - { - name: '_value', - type: 'uint256', - }, - ], - name: 'transferFrom', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'decimals', - outputs: [ - { - name: '', - type: 'uint8', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_owner', - type: 'address', - }, - ], - name: 'balanceOf', - outputs: [ - { - name: 'balance', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'symbol', - outputs: [ - { - name: '', - type: 'string', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_to', - type: 'address', - }, - { - name: '_value', - type: 'uint256', - }, - ], - name: 'transfer', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_owner', - type: 'address', - }, - { - name: '_spender', - type: 'address', - }, - ], - name: 'allowance', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - payable: true, - stateMutability: 'payable', - type: 'fallback', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - name: 'owner', - type: 'address', - }, - { - indexed: true, - name: 'spender', - type: 'address', - }, - { - indexed: false, - name: 'value', - type: 'uint256', - }, - ], - name: 'Approval', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - name: 'from', - type: 'address', - }, - { - indexed: true, - name: 'to', - type: 'address', - }, - { - indexed: false, - name: 'value', - type: 'uint256', - }, - ], - name: 'Transfer', - type: 'event', - }, -] diff --git a/src/Lighthouse/payPerDeal/fund/abi/lighthouseContract.ts b/src/Lighthouse/payPerDeal/fund/abi/lighthouseContract.ts deleted file mode 100644 index a412fb39..00000000 --- a/src/Lighthouse/payPerDeal/fund/abi/lighthouseContract.ts +++ /dev/null @@ -1,392 +0,0 @@ -export default [ - { - inputs: [ - { - internalType: 'address', - name: 'initialOwner', - type: 'address', - }, - ], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'ENDOWMENT_TRANSFER_FAILED', - type: 'error', - }, - { - inputs: [], - name: 'INSUFFICIENT_CONTRACT_BALANCE', - type: 'error', - }, - { - inputs: [], - name: 'INSUFFICIENT_USER_BALANCE', - type: 'error', - }, - { - inputs: [], - name: 'INVALID_ZERO_ADDRESS', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'owner', - type: 'address', - }, - ], - name: 'OwnableInvalidOwner', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'OwnableUnauthorizedAccount', - type: 'error', - }, - { - inputs: [], - name: 'TOKEN_APPROVAL_FAILED', - type: 'error', - }, - { - inputs: [], - name: 'TOKEN_NOT_SUPPORTED', - type: 'error', - }, - { - inputs: [], - name: 'TOKEN_PAYMENT_FAILED', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'previousOwner', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'newOwner', - type: 'address', - }, - ], - name: 'OwnershipTransferred', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'txId', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint256', - name: 'timestamp', - type: 'uint256', - }, - { - indexed: false, - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'ReceivedPayment', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'receiver', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - indexed: true, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'TokenTransferred', - type: 'event', - }, - { - stateMutability: 'payable', - type: 'fallback', - }, - { - inputs: [], - name: 'endowment', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'filForwarder', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_token', - type: 'address', - }, - ], - name: 'getERC20Balance', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'getNativeBalance', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_token', - type: 'address', - }, - ], - name: 'getTokenStatus', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'owner', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '_amount', - type: 'uint256', - }, - { - internalType: 'address', - name: '_token', - type: 'address', - }, - ], - name: 'receiveToken', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'renounceOwnership', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_endowmentAddress', - type: 'address', - }, - ], - name: 'setEndowment', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_filForwarder', - type: 'address', - }, - ], - name: 'setFilForwarder', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - name: 'tokenStatus', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newOwner', - type: 'address', - }, - ], - name: 'transferOwnership', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_token', - type: 'address', - }, - { - internalType: 'uint256', - name: '_amount', - type: 'uint256', - }, - ], - name: 'transferToEndowment', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes', - name: '_destination', - type: 'bytes', - }, - { - internalType: 'uint256', - name: '_amount', - type: 'uint256', - }, - ], - name: 'transferToOldAddress', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_tokenAddress', - type: 'address', - }, - { - internalType: 'bool', - name: '_status', - type: 'bool', - }, - ], - name: 'updateERC20Token', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - stateMutability: 'payable', - type: 'receive', - }, -] diff --git a/src/Lighthouse/payPerDeal/fund/browser.ts b/src/Lighthouse/payPerDeal/fund/browser.ts deleted file mode 100644 index 31bdad1a..00000000 --- a/src/Lighthouse/payPerDeal/fund/browser.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* istanbul ignore file */ -import { ethers } from 'ethers' -import erc20 from './abi/erc20' -import lighthuseContract from './abi/lighthouseContract' -import { lighthouseConfig } from '../../../lighthouse.config' - -export default async (amount: number, network: string, token: string) => { - try { - const config = lighthouseConfig[network] - if (!config) { - throw new Error('Unsupported Network!!!') - } - //@ts-ignore - const provider = new ethers.BrowserProvider((window as any).ethereum) - const getFeeData = await provider.getFeeData() - const signer = await provider.getSigner() - if (token.toLowerCase() === 'native') { - const gasEstimate = await signer.estimateGas({ - to: config.lighthouse_contract_address, - value: amount, - }) - const tx = await signer.sendTransaction({ - to: config.lighthouse_contract_address, - value: amount, - gasLimit: gasEstimate, - gasPrice: getFeeData.gasPrice, - }) - await tx.wait() - return tx - } else { - const tokenAddress = config[`${token.toLowerCase()}_contract_address`] - const paymentContract = new ethers.Contract( - config.lighthouse_contract_address, - lighthuseContract, - signer - ) - const erc20Contract = new ethers.Contract(tokenAddress, erc20, signer) - const approvalData = erc20Contract.interface.encodeFunctionData( - 'approve', - [config.lighthouse_contract_address, amount] - ) - const approvalTxObject = { - to: tokenAddress, - data: approvalData, - } - const gasEstimateForApproval = await signer.estimateGas(approvalTxObject) - const approvalTx = await erc20Contract.approve( - config.lighthouse_contract_address, - amount, - { - gasLimit: gasEstimateForApproval, - gasPrice: getFeeData.gasPrice, - } - ) - await approvalTx.wait() - const transferData = paymentContract.interface.encodeFunctionData( - 'receiveToken', - [amount, tokenAddress] - ) - const transferTxObject = { - to: config.lighthouse_contract_address, - data: transferData, - } - const gasEstimateForTransfer = await signer.estimateGas(transferTxObject) - const tx = await paymentContract.receiveToken(amount, tokenAddress, { - gasLimit: gasEstimateForTransfer, - gasPrice: getFeeData.gasPrice, - }) - await tx.wait() - return tx - } - } catch (error: any) { - throw new Error(error.message) - } -} diff --git a/src/Lighthouse/payPerDeal/fund/index.ts b/src/Lighthouse/payPerDeal/fund/index.ts deleted file mode 100644 index bbaea998..00000000 --- a/src/Lighthouse/payPerDeal/fund/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -import node from './node' -import browser from './browser' - -export default async ( - amount: number, - network: string, - token: string, - privateKey?: string -) => { - // Upload File to IPFS - //@ts-ignore - if (typeof window === 'undefined') { - return await node(amount, network, token, privateKey) - } else { - return await browser(amount, network, token) - } -} diff --git a/src/Lighthouse/payPerDeal/fund/node.ts b/src/Lighthouse/payPerDeal/fund/node.ts deleted file mode 100644 index 7da075ca..00000000 --- a/src/Lighthouse/payPerDeal/fund/node.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* istanbul ignore file */ -import { ethers } from 'ethers' -import erc20 from './abi/erc20' -import lighthuseContract from './abi/lighthouseContract' -import { lighthouseConfig } from '../../../lighthouse.config' - -export default async ( - amount: number, - network: string, - token: string, - privateKey: string | undefined -) => { - try { - if (!privateKey) { - throw new Error('Private Key not found!!!') - } - const config = lighthouseConfig[network] - if (!config) { - throw new Error('Unsupported Network!!!') - } - const provider = new ethers.JsonRpcProvider(config.rpc) - const getFeeData = await provider.getFeeData() - const signer = new ethers.Wallet(privateKey, provider) - if (token.toLowerCase() === 'native') { - const gasEstimate = await signer.estimateGas({ - to: config.lighthouse_contract_address, - value: amount, - }) - const tx = await signer.sendTransaction({ - to: config.lighthouse_contract_address, - value: amount, - gasLimit: gasEstimate, - gasPrice: getFeeData.gasPrice, - }) - await tx.wait() - return tx - } else { - const tokenAddress = config[`${token.toLowerCase()}_contract_address`] - const paymentContract = new ethers.Contract( - config.lighthouse_contract_address, - lighthuseContract, - signer - ) - const erc20Contract = new ethers.Contract(tokenAddress, erc20, signer) - const approvalData = erc20Contract.interface.encodeFunctionData( - 'approve', - [config.lighthouse_contract_address, amount] - ) - const approvalTxObject = { - to: tokenAddress, - data: approvalData, - } - const gasEstimateForApproval = await signer.estimateGas(approvalTxObject) - const approvalTx = await erc20Contract.approve( - config.lighthouse_contract_address, - amount, - { - gasLimit: gasEstimateForApproval, - gasPrice: getFeeData.gasPrice, - } - ) - await approvalTx.wait() - const transferData = paymentContract.interface.encodeFunctionData( - 'receiveToken', - [amount, tokenAddress] - ) - const transferTxObject = { - to: config.lighthouse_contract_address, - data: transferData, - } - const gasEstimateForTransfer = await signer.estimateGas(transferTxObject) - const tx = await paymentContract.receiveToken(amount, tokenAddress, { - gasLimit: gasEstimateForTransfer, - gasPrice: getFeeData.gasPrice, - }) - await tx.wait() - return tx - } - } catch (error: any) { - throw new Error(error.message) - } -} diff --git a/src/Lighthouse/payPerDeal/getPrice/index.ts b/src/Lighthouse/payPerDeal/getPrice/index.ts deleted file mode 100644 index 0e1f402b..00000000 --- a/src/Lighthouse/payPerDeal/getPrice/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -import node from './node' -import web from './web' - -export default async ( - pathOrSize: string | number | any, - network: string, - token?: string -) => { - // Upload File to IPFS - //@ts-ignore - if (typeof window === 'undefined') { - return await node(pathOrSize, network, token) - } else { - return await web(pathOrSize, network, token) - } -} diff --git a/src/Lighthouse/payPerDeal/getPrice/node.ts b/src/Lighthouse/payPerDeal/getPrice/node.ts deleted file mode 100644 index cbdf1b3f..00000000 --- a/src/Lighthouse/payPerDeal/getPrice/node.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { ethers } from 'ethers' -import { lighthouseConfig } from '../../../lighthouse.config' - -const getTickerPrice = async (symbol: string): Promise => { - try { - const response = await fetch( - `${lighthouseConfig.lighthouseAPI}/api/lighthouse/get_ticker?symbol=${symbol}` - ) - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`) - } - const data = (await response.json()) as number - return data - } catch (error: any) { - throw new Error(`Failed to get ticker price: ${error.message}`) - } -} - -const calculatePrice = async ( - size: number, - network: string, - token?: string -) => { - const minFileSizeInBytes = 1048576 // 1MB - const chargeableSizeInMB = Math.max(size, minFileSizeInBytes) / 1048576 - const dollarPricePerMB = 0.00390625 - const cost = dollarPricePerMB * chargeableSizeInMB - if (token === 'usdc' || token === 'usdt' || token === 'dai') { - const decimals = lighthouseConfig[network][`${token}_contract_decimal`] - const priceTODecimals = cost.toFixed(decimals) - const priceInSmallestUnits = ethers.parseUnits( - priceTODecimals.toString(), - decimals - ) - return priceInSmallestUnits - } - const tokenPriceInUSD = await getTickerPrice( - lighthouseConfig[network]['symbol'] - ) - const priceInToken = cost / tokenPriceInUSD - const priceToDecimals = priceInToken.toFixed( - lighthouseConfig[network].native_decimal - ) - const priceInSmallestUnits = ethers.parseUnits( - priceToDecimals.toString(), - lighthouseConfig[network].native_decimal - ) - return priceInSmallestUnits -} - -export default async ( - pathOrSize: string | number, - network: string, - token?: string -): Promise => { - try { - if (!network) { - throw new Error('Token not provided!!!') - } - if (typeof pathOrSize === 'string') { - const { lstatSync } = eval(`require`)('fs-extra') - const { size } = lstatSync(pathOrSize) - const price = calculatePrice( - size, - network.toLowerCase(), - token?.toLowerCase() - ) - return price - } else { - const price = calculatePrice( - pathOrSize, - network.toLowerCase(), - token?.toLowerCase() - ) - return price - } - } catch (error: any) { - throw new Error(error.message) - } -} diff --git a/src/Lighthouse/payPerDeal/getPrice/web.ts b/src/Lighthouse/payPerDeal/getPrice/web.ts deleted file mode 100644 index 4060631c..00000000 --- a/src/Lighthouse/payPerDeal/getPrice/web.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* istanbul ignore file */ -import { ethers } from 'ethers' -import { lighthouseConfig } from '../../../lighthouse.config' - -const getTickerPrice = async (symbol: string): Promise => { - try { - const response = await fetch( - `${lighthouseConfig.lighthouseAPI}/api/lighthouse/get_ticker?symbol=${symbol}` - ) - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`) - } - const data = (await response.json()) as number - return data - } catch (error: any) { - throw new Error(`Failed to get ticker price: ${error.message}`) - } -} - -const calculatePrice = async ( - size: number, - network: string, - token?: string -) => { - const minFileSizeInBytes = 1048576 // 1MB - const chargeableSizeInMB = Math.max(size, minFileSizeInBytes) / 1048576 - const dollarPricePerMB = 0.00390625 - const cost = dollarPricePerMB * chargeableSizeInMB - if (token === 'usdc' || token === 'usdt' || token === 'dai') { - const decimals = lighthouseConfig[network][`${token}_contract_decimal`] - const priceTODecimals = cost.toFixed(decimals) - const priceInSmallestUnits = ethers.parseUnits( - priceTODecimals.toString(), - decimals - ) - return priceInSmallestUnits - } - const tokenPriceInUSD = await getTickerPrice( - lighthouseConfig[network]['symbol'] - ) - const priceInToken = cost / tokenPriceInUSD - const priceToDecimals = priceInToken.toFixed( - lighthouseConfig[network].native_decimal - ) - const priceInSmallestUnits = ethers.parseUnits( - priceToDecimals.toString(), - lighthouseConfig[network].native_decimal - ) - return priceInSmallestUnits -} - -export default async ( - pathOrSize: any | number, - network: string, - token?: string -): Promise => { - try { - if (!network) { - throw new Error('Token not provided!!!') - } - if (typeof pathOrSize === 'number') { - const price = calculatePrice( - pathOrSize, - network.toLowerCase(), - token?.toLowerCase() - ) - return price - } else { - let totalSize = 0 - for (let i = 0; i < pathOrSize.length; i++) { - totalSize = totalSize + pathOrSize[i]['size'] - } - const price = calculatePrice( - totalSize, - network.toLowerCase(), - token?.toLowerCase() - ) - return price - } - } catch (error: any) { - throw new Error(error.message) - } -} diff --git a/src/Lighthouse/payPerDeal/oneTimeAuth/index.ts b/src/Lighthouse/payPerDeal/oneTimeAuth/index.ts deleted file mode 100644 index 04ce12d8..00000000 --- a/src/Lighthouse/payPerDeal/oneTimeAuth/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import node from './node' -import web from './web' - -export default async (privateKey?: string) => { - // Upload File to IPFS - //@ts-ignore - if (typeof window === 'undefined') { - return await node(privateKey) - } else { - return await web() - } -} diff --git a/src/Lighthouse/payPerDeal/oneTimeAuth/node.ts b/src/Lighthouse/payPerDeal/oneTimeAuth/node.ts deleted file mode 100644 index a0874730..00000000 --- a/src/Lighthouse/payPerDeal/oneTimeAuth/node.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* istanbul ignore file */ -import { ethers } from 'ethers' -import { lighthouseConfig } from '../../../lighthouse.config' - -export default async (privateKey: string | undefined): Promise => { - try { - if (!privateKey) { - throw new Error('Private key not provided!!!') - } - const signer = new ethers.Wallet(privateKey) - const response = await fetch( - `${lighthouseConfig.lighthouseAPI}/api/auth/get_message?publicKey=${signer.address}` - ) - const message = (await response.json()) as string - const signature = await signer.signMessage(message) - return `${signer.address}$${signature}` - } catch (error: any) { - throw new Error(error.message) - } -} diff --git a/src/Lighthouse/payPerDeal/oneTimeAuth/web.ts b/src/Lighthouse/payPerDeal/oneTimeAuth/web.ts deleted file mode 100644 index 7825fdcd..00000000 --- a/src/Lighthouse/payPerDeal/oneTimeAuth/web.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* istanbul ignore file */ -import { ethers } from 'ethers' -import { lighthouseConfig } from '../../../lighthouse.config' - -export default async (): Promise => { - try { - //@ts-ignore - const provider = new ethers.BrowserProvider((window as any).ethereum) - const signer = await provider.getSigner() - const response = await fetch( - `${lighthouseConfig.lighthouseAPI}/api/auth/get_message?publicKey=${signer.address}` - ) - const message = (await response.json()) as string - const signature = await signer.signMessage(message) - return `${signer.address}$${signature}` - } catch (error: any) { - throw new Error(error.message) - } -} diff --git a/src/Lighthouse/podsi/index.ts b/src/Lighthouse/podsi/index.ts deleted file mode 100644 index d6f9131b..00000000 --- a/src/Lighthouse/podsi/index.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { defaultConfig } from '../../lighthouse.config' - -type Proof = { - verifierData: { - commPc: string - sizePc: string - } - inclusionProof: { - proofIndex: { - index: string - path: string[] - } - proofSubtree: { - index: string - path: string[] - } - indexRecord: { - checksum: string - proofIndex: string - proofSubtree: number - size: number - } - } -} - -type DealInfo = { - dealId: number - storageProvider: string - proof: Proof -} - -type PODSIData = { - pieceCID: string - dealInfo: DealInfo[] -} - -export default async (cid: string): Promise<{ data: PODSIData }> => { - try { - const response = await fetch( - defaultConfig.lighthouseAPI + `/api/lighthouse/get_proof?cid=${cid}` - ) - if (!response.ok) { - if (response.status === 400) { - throw new Error("Proof Doesn't exist yet") - } - throw new Error(`Request failed with status code ${response.status}`) - } - const data = (await response.json()) as PODSIData - return { data } - } catch (error: any) { - if (error?.response?.status === 400) { - throw new Error("Proof Doesn't exist yet") - } - throw new Error(error.message) - } -} diff --git a/src/Lighthouse/upload/buffer/browser.ts b/src/Lighthouse/upload/buffer/browser.ts index fa8543b9..73fefa0d 100644 --- a/src/Lighthouse/upload/buffer/browser.ts +++ b/src/Lighthouse/upload/buffer/browser.ts @@ -1,9 +1,16 @@ import { lighthouseConfig } from '../../../lighthouse.config' +import type { Headers } from '../../../types' -export default async (blob: any, apiKey: string, cidVersion: number) => { +export default async ( + blob: any, + apiKey: string, + cidVersion: number, + headers?: Headers +) => { try { const token = 'Bearer ' + apiKey const endpoint = lighthouseConfig.lighthouseNode + `/api/v0/add?cid-version=${cidVersion}` + const storageType = headers?.storageType // Upload file const formData = new FormData() @@ -14,6 +21,7 @@ export default async (blob: any, apiKey: string, cidVersion: number) => { body: formData, headers: { Authorization: token, + ...(storageType ? { 'X-Storage-Type': storageType } : {}), }, }) diff --git a/src/Lighthouse/upload/buffer/index.ts b/src/Lighthouse/upload/buffer/index.ts index 9e798294..96dacc54 100644 --- a/src/Lighthouse/upload/buffer/index.ts +++ b/src/Lighthouse/upload/buffer/index.ts @@ -1,12 +1,22 @@ import uploadBuffer from './node' import uploadTypedArray from './browser' +import type { UploadOptions } from '../../../types' + +export default async ( + buffer: any, + apiKey: string, + options: UploadOptions = { + cidVersion: 1, + headers: {}, + } +) => { + const { cidVersion = 1, headers } = options -export default async (buffer: any, apiKey: string, cidVersion: number = 1) => { // Upload File to IPFS //@ts-ignore if (typeof window === 'undefined') { - return await uploadBuffer(buffer, apiKey, cidVersion) + return await uploadBuffer(buffer, apiKey, cidVersion, headers) } else { - return await uploadTypedArray(buffer, apiKey, cidVersion) + return await uploadTypedArray(buffer, apiKey, cidVersion, headers) } } diff --git a/src/Lighthouse/upload/buffer/node.ts b/src/Lighthouse/upload/buffer/node.ts index 11be7f51..f31a1f33 100644 --- a/src/Lighthouse/upload/buffer/node.ts +++ b/src/Lighthouse/upload/buffer/node.ts @@ -1,9 +1,16 @@ import { lighthouseConfig } from '../../../lighthouse.config' +import type { Headers } from '../../../types' -export default async (buffer: any, apiKey: string, cidVersion: number) => { +export default async ( + buffer: any, + apiKey: string, + cidVersion: number, + headers?: Headers +) => { try { const token = 'Bearer ' + apiKey const endpoint = lighthouseConfig.lighthouseNode + `/api/v0/add?cid-version=${cidVersion}` + const storageType = headers?.storageType // Upload file const blob = new Blob([buffer]) @@ -14,7 +21,8 @@ export default async (buffer: any, apiKey: string, cidVersion: number) => { method: 'POST', body: formData, headers: { - Authorization: token + Authorization: token, + ...(storageType ? { 'X-Storage-Type': storageType } : {}), }, }) diff --git a/src/Lighthouse/upload/car/browser.ts b/src/Lighthouse/upload/car/browser.ts new file mode 100644 index 00000000..e9ef458c --- /dev/null +++ b/src/Lighthouse/upload/car/browser.ts @@ -0,0 +1,65 @@ +/* istanbul ignore file */ +import { lighthouseConfig } from '../../../lighthouse.config' +import type { IUploadProgressCallback, IFileUploadedResponse, Headers } from '../../../types' +import { fetchWithTimeout } from '../../utils/util' + +export default async ( + file: File, + accessToken: string, + headers?: Headers, + uploadProgressCallback?: (data: IUploadProgressCallback) => void +): Promise<{ data: IFileUploadedResponse }> => { + try { + // Validate that only a single file is provided + if (!file || !(file instanceof File)) { + throw new Error('CAR upload requires a single File object') + } + + const ext = file.name.split('.').pop()?.toLowerCase() + if (ext !== 'car') { + throw new Error('File must have a .car extension') + } + + const endpoint = lighthouseConfig.lighthouseNode + '/api/v0/dag/import' + + const formData = new FormData() + formData.append('file', file) + + const token = 'Bearer ' + accessToken + const storageType = headers?.storageType + + const requestHeaders = { + Authorization: token, + ...(storageType ? { 'X-Storage-Type': storageType } : {}), + } + + const response = uploadProgressCallback + ? await fetchWithTimeout(endpoint, { + method: 'POST', + body: formData, + headers: requestHeaders, + timeout: 7200000, + onProgress: (progress) => { + uploadProgressCallback({ + progress: progress, + }) + }, + }) + : await fetchWithTimeout(endpoint, { + method: 'POST', + body: formData, + headers: requestHeaders, + timeout: 7200000, + }) + + if (!response.ok) { + const res = await response.json() + throw new Error(res.error) + } + + const responseData = await response.json() + return { data: responseData } + } catch (error: any) { + throw new Error(error) + } +} diff --git a/src/Lighthouse/upload/car/index.ts b/src/Lighthouse/upload/car/index.ts new file mode 100644 index 00000000..15fd1889 --- /dev/null +++ b/src/Lighthouse/upload/car/index.ts @@ -0,0 +1,40 @@ +import uploadCARNode from './node' +import uploadCARBrowser from './browser' +import type { IFileUploadedResponse, IUploadProgressCallback, UploadFilesOptions } from '../../../types' + +/** + * Upload a CAR (Content Addressable aRchive) file to Lighthouse + * @param pathOrFile - File path (Node.js) or File object (browser) + * @param apiKey - Lighthouse API key + * @param options - Optional options for the upload + * @returns Promise with uploaded file data + */ +async function uploadCAR( + pathOrFile: string | File, + apiKey: string, + options: UploadFilesOptions = { + headers: {}, + onProgress: (data: IUploadProgressCallback) => { + return + }, + } +): Promise<{ data: IFileUploadedResponse }> { + const { cidVersion = 1, headers, onProgress } = options + + // @ts-ignore + if (typeof window === 'undefined') { + // Node.js environment + if (typeof pathOrFile !== 'string') { + throw new Error('In Node.js environment, provide a file path string') + } + return await uploadCARNode(pathOrFile, apiKey, headers, onProgress) + } else { + // Browser environment + if (typeof pathOrFile === 'string') { + throw new Error('In browser environment, provide a File object') + } + return await uploadCARBrowser(pathOrFile as File, apiKey, headers, onProgress) + } +} + +export default uploadCAR diff --git a/src/Lighthouse/upload/car/node.ts b/src/Lighthouse/upload/car/node.ts new file mode 100644 index 00000000..1ad05810 --- /dev/null +++ b/src/Lighthouse/upload/car/node.ts @@ -0,0 +1,67 @@ +import { lighthouseConfig } from '../../../lighthouse.config' +import { fetchWithDirectStream } from '../../utils/util' +import type { IFileUploadedResponse, IUploadProgressCallback, Headers } from '../../../types' + +export default async ( + sourcePath: string, + apiKey: string, + headers?: Headers, + uploadProgressCallback?: (data: IUploadProgressCallback) => void +): Promise<{ data: IFileUploadedResponse }> => { + const { createReadStream, lstatSync } = eval(`require`)('fs-extra') + const path = eval(`require`)('path') + + const token = 'Bearer ' + apiKey + const stats = lstatSync(sourcePath) + + if (!stats.isFile()) { + throw new Error('CAR upload only supports single file upload') + } + + // Validate .car extension + const ext = path.extname(sourcePath).toLowerCase() + if (ext !== '.car') { + throw new Error('File must have a .car extension') + } + + try { + const endpoint = lighthouseConfig.lighthouseNode + '/api/v0/dag/import' + const boundary = + '----WebKitFormBoundary' + Math.random().toString(16).substr(2) + + const storageType = headers?.storageType + const requestHeaders = { + Authorization: token, + ...(storageType ? { 'X-Storage-Type': storageType } : {}), + } + + const stream = createReadStream(sourcePath) + const streamData = { + boundary, + files: [ + { + stream, + filename: path.basename(sourcePath), + size: stats.size, + }, + ], + } + + const response = await fetchWithDirectStream( + endpoint, + { + method: 'POST', + headers: requestHeaders, + timeout: 7200000, + onProgress: uploadProgressCallback + ? (data: { progress: number }) => uploadProgressCallback(data) + : undefined, + }, + streamData + ) + + return response + } catch (error: any) { + throw new Error(error) + } +} diff --git a/src/Lighthouse/upload/files/browser.ts b/src/Lighthouse/upload/files/browser.ts index 505347da..c667c7e1 100644 --- a/src/Lighthouse/upload/files/browser.ts +++ b/src/Lighthouse/upload/files/browser.ts @@ -11,14 +11,31 @@ export default async ( files: any, accessToken: string, cidVersion: number, - uploadProgressCallback?: (data: IUploadProgressCallback) => void + optionsHeaders?: { storageType?: string }, + uploadProgressCallback?: (data: IUploadProgressCallback) => void, ): Promise<{ data: IFileUploadedResponse }> => { try { const isDirectory = [...files].some(file => file.webkitRelativePath) - let endpoint = lighthouseConfig.lighthouseNode + `/api/v0/add?wrap-with-directory=false&cid-version=${cidVersion}` + + const storageType = optionsHeaders?.storageType + + // Build query string with allowed params only + const baseParams = { + 'cid-version': String(cidVersion), + } + + const queryParams = new URLSearchParams({ + 'wrap-with-directory': 'false', + ...baseParams, + }) + let endpoint = lighthouseConfig.lighthouseNode + `/api/v0/add?${queryParams.toString()}` if(!isDirectory && files.length > 1) { - endpoint = lighthouseConfig.lighthouseNode + `/api/v0/add?wrap-with-directory=true&cid-version=${cidVersion}` + const wrapParams = new URLSearchParams({ + 'wrap-with-directory': 'true', + ...baseParams, + }) + endpoint = lighthouseConfig.lighthouseNode + `/api/v0/add?${wrapParams.toString()}` } const formData = new FormData() @@ -29,7 +46,8 @@ export default async ( const token = 'Bearer ' + accessToken const headers = new Headers({ - Authorization: token + Authorization: token, + ...(storageType ? { 'X-Storage-Type': storageType } : {}), }) const response = uploadProgressCallback diff --git a/src/Lighthouse/upload/files/index.ts b/src/Lighthouse/upload/files/index.ts index 82bc6e45..73526df5 100644 --- a/src/Lighthouse/upload/files/index.ts +++ b/src/Lighthouse/upload/files/index.ts @@ -2,26 +2,33 @@ import uploadFile from './node' import uploadFileBrowser from './browser' import { IUploadProgressCallback, - IFileUploadedResponse + IFileUploadedResponse, + UploadFilesOptions } from '../../../types' async function uploadFiles( path: string | any, apiKey: string, - cidVersion: number = 1, + cidVersionOrOptions: number | UploadFilesOptions = 1, uploadProgressCallback?: (data: IUploadProgressCallback) => void ): Promise<{ data: IFileUploadedResponse }> { + // Normalize to options object (hybrid support) + const options: UploadFilesOptions = + typeof cidVersionOrOptions === 'number' + ? { + cidVersion: cidVersionOrOptions, + onProgress: uploadProgressCallback, + } + : cidVersionOrOptions + + const { cidVersion = 1, onProgress, headers } = options + // Upload File to IPFS //@ts-ignore if (typeof window === 'undefined') { - return await uploadFile(path, apiKey, cidVersion, uploadProgressCallback) + return await uploadFile(path, apiKey, cidVersion, headers, onProgress) } else { - return await uploadFileBrowser( - path, - apiKey, - cidVersion, - uploadProgressCallback - ) + return await uploadFileBrowser(path, apiKey, cidVersion, headers, onProgress) } } diff --git a/src/Lighthouse/upload/files/node.ts b/src/Lighthouse/upload/files/node.ts index 80bc1f02..d1714fb5 100644 --- a/src/Lighthouse/upload/files/node.ts +++ b/src/Lighthouse/upload/files/node.ts @@ -25,7 +25,8 @@ export default async ( sourcePath: string, apiKey: string, cidVersion: number, - uploadProgressCallback?: (data: IUploadProgressCallback) => void + optionsHeaders?: { storageType?: string }, + uploadProgressCallback?: (data: IUploadProgressCallback) => void, ): Promise<{ data: IFileUploadedResponse }> => { const { createReadStream, lstatSync } = eval(`require`)('fs-extra') const path = eval(`require`)('path') @@ -34,14 +35,21 @@ export default async ( const stats = lstatSync(sourcePath) try { + const storageType = optionsHeaders?.storageType + + // Build query string with allowed params only + const queryParams = new URLSearchParams({ + 'wrap-with-directory': 'false', + 'cid-version': String(cidVersion), + }) const endpoint = - lighthouseConfig.lighthouseNode + - `/api/v0/add?wrap-with-directory=false&cid-version=${cidVersion}` + lighthouseConfig.lighthouseNode + `/api/v0/add?${queryParams.toString()}` const boundary = - '----WebKitFormBoundary' + Math.random().toString(16).substr(2) + '----WebKitFormBoundary' + Math.random().toString(16).slice(2) - const headers = { + const requestHeaders = { Authorization: token, + ...(storageType ? { 'X-Storage-Type': storageType } : {}), } if (stats.isFile()) { @@ -61,7 +69,7 @@ export default async ( endpoint, { method: 'POST', - headers, + headers: requestHeaders, timeout: 7200000, onProgress: uploadProgressCallback ? (data: { progress: number }) => uploadProgressCallback(data) @@ -93,7 +101,7 @@ export default async ( endpoint, { method: 'POST', - headers, + headers: requestHeaders, timeout: 7200000, onProgress: uploadProgressCallback ? (data: { progress: number }) => uploadProgressCallback(data) diff --git a/src/Lighthouse/upload/text/browser.ts b/src/Lighthouse/upload/text/browser.ts index f46b90e9..72aadfbe 100644 --- a/src/Lighthouse/upload/text/browser.ts +++ b/src/Lighthouse/upload/text/browser.ts @@ -1,10 +1,18 @@ import { lighthouseConfig } from '../../../lighthouse.config' import { fetchWithTimeout } from '../../utils/util' +import type { Headers } from '../../../types' -export default async (text: string, apiKey: string, name: string, cidVersion: number) => { +export default async ( + text: string, + apiKey: string, + name: string, + cidVersion: number, + headers?: Headers +) => { try { const token = 'Bearer ' + apiKey const endpoint = lighthouseConfig.lighthouseNode + `/api/v0/add?cid-version=${cidVersion}` + const storageType = headers?.storageType // Upload file const formData = new FormData() @@ -17,6 +25,7 @@ export default async (text: string, apiKey: string, name: string, cidVersion: nu timeout: 7200000, headers: { Authorization: token, + ...(storageType ? { 'X-Storage-Type': storageType } : {}), }, }) diff --git a/src/Lighthouse/upload/text/index.ts b/src/Lighthouse/upload/text/index.ts index 4d645a9a..8477741d 100644 --- a/src/Lighthouse/upload/text/index.ts +++ b/src/Lighthouse/upload/text/index.ts @@ -1,12 +1,23 @@ import uploadTextServer from './node' import uploadTextBrowser from './browser' +import type { UploadOptions } from '../../../types' + +export default async ( + text: string, + apiKey: string, + name = 'text', + options: UploadOptions = { + cidVersion: 1, + headers: {}, + } +) => { + const { cidVersion = 1, headers } = options -export default async (text: string, apiKey: string, name = 'text', cidVersion: number = 1) => { // Upload File to IPFS //@ts-ignore if (typeof window === 'undefined') { - return await uploadTextServer(text, apiKey, name, cidVersion) + return await uploadTextServer(text, apiKey, name, cidVersion, headers) } else { - return await uploadTextBrowser(text, apiKey, name, cidVersion) + return await uploadTextBrowser(text, apiKey, name, cidVersion, headers) } } diff --git a/src/Lighthouse/upload/text/node.ts b/src/Lighthouse/upload/text/node.ts index 8c2257cb..bc8e862d 100644 --- a/src/Lighthouse/upload/text/node.ts +++ b/src/Lighthouse/upload/text/node.ts @@ -1,10 +1,18 @@ import { lighthouseConfig } from '../../../lighthouse.config' import { fetchWithTimeout } from '../../utils/util' +import type { Headers } from '../../../types' -export default async (text: string, apiKey: string, name: string, cidVersion: number) => { +export default async ( + text: string, + apiKey: string, + name: string, + cidVersion: number, + headers?: Headers +) => { try { const token = 'Bearer ' + apiKey const endpoint = lighthouseConfig.lighthouseNode + `/api/v0/add?cid-version=${cidVersion}` + const storageType = headers?.storageType // Upload file const formData = new FormData() @@ -19,6 +27,7 @@ export default async (text: string, apiKey: string, name: string, cidVersion: nu timeout: 7200000, headers: { Authorization: token, + ...(storageType ? { 'X-Storage-Type': storageType } : {}), }, }) diff --git a/src/Lighthouse/uploadEncrypted/encrypt/file/browser.ts b/src/Lighthouse/uploadEncrypted/encrypt/file/browser.ts index c833343c..756e6c21 100644 --- a/src/Lighthouse/uploadEncrypted/encrypt/file/browser.ts +++ b/src/Lighthouse/uploadEncrypted/encrypt/file/browser.ts @@ -3,6 +3,7 @@ import { generate, saveShards } from '@lighthouse-web3/kavach' import { IFileUploadedResponse, IUploadProgressCallback, + Headers, } from '../../../../types' import { encryptFile } from '../../encryptionBrowser' import { lighthouseConfig } from '../../../../lighthouse.config' @@ -30,7 +31,8 @@ export default async ( publicKey: string, auth_token: string, cidVersion: number, - uploadProgressCallback?: (data: IUploadProgressCallback) => void + optionsHeaders?: Headers, + uploadProgressCallback?: (data: IUploadProgressCallback) => void, ): Promise<{ data: IFileUploadedResponse[] }> => { try { let keyMap = {} as any @@ -41,6 +43,7 @@ export default async ( const endpoint = lighthouseConfig.lighthouseNode + `/api/v0/add?wrap-with-directory=false&cid-version=${cidVersion}` const token = 'Bearer ' + apiKey + const storageType = optionsHeaders?.storageType const fileArr = [] for (let i = 0; i < files.length; i++) { @@ -82,6 +85,7 @@ export default async ( headers: { Encryption: `${true}`, Authorization: token, + ...(storageType ? { 'X-Storage-Type': storageType } : {}), }, onProgress: (progress) => { uploadProgressCallback({ @@ -96,6 +100,7 @@ export default async ( headers: { Encryption: `${true}`, Authorization: token, + ...(storageType ? { 'X-Storage-Type': storageType } : {}), }, }) if (!response.ok) { diff --git a/src/Lighthouse/uploadEncrypted/encrypt/file/index.ts b/src/Lighthouse/uploadEncrypted/encrypt/file/index.ts index cb996fe7..42d0b8bf 100644 --- a/src/Lighthouse/uploadEncrypted/encrypt/file/index.ts +++ b/src/Lighthouse/uploadEncrypted/encrypt/file/index.ts @@ -1,18 +1,43 @@ import browser from './browser' import uploadFile from './node' +import { UploadFilesOptions } from '../../../../types' export default async ( path: string | any, apiKey: string, publicKey: string, signedMessage: string, - cidVersion: number = 1, + cidVersionOrOptions: number | UploadFilesOptions = 1, uploadProgressCallback?: (data: any) => void ) => { + // Normalize to options object (hybrid support) + const options: UploadFilesOptions = + typeof cidVersionOrOptions === 'number' + ? { + cidVersion: cidVersionOrOptions, + onProgress: uploadProgressCallback, + } + : cidVersionOrOptions + + const { cidVersion = 1, onProgress, headers } = options + const progressCallback = + onProgress || + uploadProgressCallback || + (() => { + return + }) + // Upload File to IPFS //@ts-ignore if (typeof window === 'undefined') { - return await uploadFile(path, apiKey, publicKey, signedMessage, cidVersion) + return await uploadFile( + path, + apiKey, + publicKey, + signedMessage, + cidVersion, + headers + ) } else { return await browser( path, @@ -20,10 +45,8 @@ export default async ( publicKey, signedMessage, cidVersion, - uploadProgressCallback || - (() => { - return - }) + headers, + progressCallback, ) } } diff --git a/src/Lighthouse/uploadEncrypted/encrypt/file/node.ts b/src/Lighthouse/uploadEncrypted/encrypt/file/node.ts index 0a9d803e..4e4d7917 100644 --- a/src/Lighthouse/uploadEncrypted/encrypt/file/node.ts +++ b/src/Lighthouse/uploadEncrypted/encrypt/file/node.ts @@ -2,7 +2,7 @@ import { lighthouseConfig } from '../../../../lighthouse.config' import { generate, saveShards } from '@lighthouse-web3/kavach' import { encryptFile } from '../../encryptionNode' import { walk } from '../../../upload/files/node' -import { IFileUploadedResponse } from '../../../../types' +import { IFileUploadedResponse, Headers } from '../../../../types' import { fetchWithTimeout } from '../../../utils/util' export default async ( @@ -10,10 +10,12 @@ export default async ( apiKey: string, publicKey: string, auth_token: string, - cidVersion: number + cidVersion: number, + optionsHeaders?: Headers, ): Promise<{ data: IFileUploadedResponse[] }> => { const fs = eval('require')('fs-extra') const token = 'Bearer ' + apiKey + const storageType = optionsHeaders?.storageType const endpoint = lighthouseConfig.lighthouseNode + `/api/v0/add?wrap-with-directory=false&cid-version=${cidVersion}` @@ -37,6 +39,7 @@ export default async ( headers: { Encryption: 'true', Authorization: token, + ...(storageType ? { 'X-Storage-Type': storageType } : {}), }, }) @@ -91,6 +94,7 @@ export default async ( headers: { Encryption: 'true', Authorization: token, + ...(storageType ? { 'X-Storage-Type': storageType } : {}), }, }) diff --git a/src/Lighthouse/uploadEncrypted/encrypt/text/browser.ts b/src/Lighthouse/uploadEncrypted/encrypt/text/browser.ts index 7af16778..34a368a6 100644 --- a/src/Lighthouse/uploadEncrypted/encrypt/text/browser.ts +++ b/src/Lighthouse/uploadEncrypted/encrypt/text/browser.ts @@ -3,17 +3,22 @@ import { encryptFile } from '../../encryptionBrowser' import { generate, saveShards } from '@lighthouse-web3/kavach' import { lighthouseConfig } from '../../../../lighthouse.config' import { fetchWithTimeout } from '../../../utils/util' +import type { Headers } from '../../../../types' export default async ( text: string, apiKey: string, publicKey: string, signedMessage: string, - name: string + name: string, + cidVersion: number, + optionsHeaders?: Headers, ) => { try { const token = 'Bearer ' + apiKey - const endpoint = lighthouseConfig.lighthouseNode + '/api/v0/add' + const endpoint = + lighthouseConfig.lighthouseNode + `/api/v0/add?cid-version=${cidVersion}` + const storageType = optionsHeaders?.storageType // Upload file const formData = new FormData() @@ -40,6 +45,7 @@ export default async ( Encryption: 'true', 'Mime-Type': 'text/plain', Authorization: token, + ...(storageType ? { 'X-Storage-Type': storageType } : {}), }, }) diff --git a/src/Lighthouse/uploadEncrypted/encrypt/text/index.ts b/src/Lighthouse/uploadEncrypted/encrypt/text/index.ts index b9a27d01..b4db77b5 100644 --- a/src/Lighthouse/uploadEncrypted/encrypt/text/index.ts +++ b/src/Lighthouse/uploadEncrypted/encrypt/text/index.ts @@ -1,17 +1,52 @@ import serverSide from './node' import browser from './browser' +import { UploadOptions, Headers } from '../../../../types' + +type EncryptedTextUpload = ( + text: string, + apiKey: string, + publicKey: string, + signedMessage: string, + name: string, + cidVersion: number, + headers?: Headers, +) => Promise export default async ( text: string, apiKey: string, publicKey: string, signedMessage: string, - name = 'text' + name = 'text', + options: UploadOptions = { + cidVersion: 1, + headers: {}, + } ) => { + const { cidVersion = 1, headers } = options + const serverSideUpload = serverSide as EncryptedTextUpload + const browserUpload = browser as EncryptedTextUpload + //@ts-ignore if (typeof window === 'undefined') { - return await serverSide(text, apiKey, publicKey, signedMessage, name) + return await serverSideUpload( + text, + apiKey, + publicKey, + signedMessage, + name, + cidVersion, + headers + ) } else { - return await browser(text, apiKey, publicKey, signedMessage, name) + return await browserUpload( + text, + apiKey, + publicKey, + signedMessage, + name, + cidVersion, + headers + ) } } diff --git a/src/Lighthouse/uploadEncrypted/encrypt/text/node.ts b/src/Lighthouse/uploadEncrypted/encrypt/text/node.ts index 8b42a24f..3e870570 100644 --- a/src/Lighthouse/uploadEncrypted/encrypt/text/node.ts +++ b/src/Lighthouse/uploadEncrypted/encrypt/text/node.ts @@ -3,17 +3,22 @@ import { encryptFile } from '../../encryptionNode' import { generate, saveShards } from '@lighthouse-web3/kavach' import { lighthouseConfig } from '../../../../lighthouse.config' import { fetchWithTimeout } from '../../../utils/util' +import type { Headers } from '../../../../types' export default async ( text: string, apiKey: string, publicKey: string, signedMessage: string, - name: string + name: string, + cidVersion: number, + headers?: Headers, ) => { try { const token = 'Bearer ' + apiKey - const endpoint = lighthouseConfig.lighthouseNode + '/api/v0/add' + const endpoint = + lighthouseConfig.lighthouseNode + `/api/v0/add?cid-version=${cidVersion}` + const storageType = headers?.storageType // Upload file const formData = new FormData() @@ -36,6 +41,7 @@ export default async ( Encryption: 'true', 'Mime-Type': 'text/plain', Authorization: token, + ...(storageType ? { 'X-Storage-Type': storageType } : {}), }, }) diff --git a/src/types.ts b/src/types.ts index 523afe29..03a07897 100644 --- a/src/types.ts +++ b/src/types.ts @@ -11,3 +11,16 @@ export interface IFileUploadedResponse { export type UploadFileReturnType = T extends true ? IFileUploadedResponse[] : IFileUploadedResponse + +export type Headers = { + storageType?: string +} +export interface UploadFilesOptions { + cidVersion?: number + onProgress?: (data: IUploadProgressCallback) => void + headers?: Headers +} +export interface UploadOptions { + cidVersion?: number + headers?: Headers +}