storacha-sol 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,14 +6,17 @@ Here are a couple of things you can do with this package:
6
6
 
7
7
  - Estimate upload fees based on the file size and duration
8
8
  - Make SOL payments for Storage on Storacha
9
+ - Multiple file (directory) uploads
10
+ - Show how much time is left to expiry
11
+ - View your upload history (all files you've stored with their details)
12
+ - Get expiration warnings via email before your files expire
13
+ - Automatic deletion of expired files from Storacha
9
14
 
10
15
  Stuffs we hope to cover or extend:
11
16
 
12
- - Multiple file (directory) uploads
13
- - List stored items in a wallet's space (space-management, pretty-much)
14
17
  - Allow payments from other chains. (Filecoin next)
15
18
  - Include implementations for other libs. Right now, we only have React. Hoping to cover, Vue, Svelte etc.
16
- - Show how much time is left to expiry and add ability to renew/icrease upload duration
19
+ - Add ability to renew/increase upload duration (coming soon! see [GitHub issues](https://github.com/seetadev/storacha-solana-sdk/issues))
17
20
 
18
21
  ## Usage
19
22
 
@@ -108,6 +111,58 @@ An edge-case you may want to consider before calling `createDeposit` is to check
108
111
 
109
112
  You can use `client.estimateStorageCost` to get the values in SOL and compare if the balance is less than what was estimated before paying and provide a reasonable error message for your end-users.
110
113
 
114
+ ### View Upload History
115
+
116
+ You can fetch all uploads associated with a wallet address:
117
+
118
+ ```ts
119
+ const client = useDeposit('testnet' as Environment);
120
+ const history = await client.getUserUploadHistory(publicKey.toString());
121
+
122
+ console.log(history.userHistory); // Array of all deposits
123
+ ```
124
+
125
+ Each deposit in the history includes:
126
+ - File details (name, size, type, CID)
127
+ - Expiration date
128
+ - Deletion status (`active`, `warned`, `deleted`)
129
+ - Transaction hash
130
+ - Duration and cost information
131
+
132
+ ### Email Expiration Warnings
133
+
134
+ When creating a deposit, you can optionally provide an email address to receive expiration warnings:
135
+
136
+ ```ts
137
+ const result = await client.createDeposit({
138
+ file,
139
+ durationDays: storageDuration,
140
+ payer: publicKey,
141
+ userEmail: 'user@example.com', // Optional email for expiration warnings
142
+ signTransaction: async (tx) => {
143
+ const signed = await signTransaction(tx);
144
+ return signed;
145
+ },
146
+ });
147
+ ```
148
+
149
+ If provided, you'll receive an email notification **7 days before your file expires**, giving you time to extend the storage duration (feature coming soon!).
150
+
151
+ The warning email includes:
152
+ - File name and CID
153
+ - Exact expiration date
154
+ - Number of days remaining
155
+ - Direct link to view your file on IPFS
156
+
157
+ ### Automatic Cleanup
158
+
159
+ Files that have expired are automatically deleted from Storacha storage. This happens through a scheduled job that:
160
+ 1. Identifies expired deposits
161
+ 2. Removes the data from Storacha (including shards)
162
+ 3. Updates the deletion status in the database
163
+
164
+ Your upload history will show the deletion status, so you can track which files are still active, warned, or deleted.
165
+
111
166
  ## Want to contribute?
112
167
 
113
168
  Read the [Contributing guide](CONTRIBUTING.md)
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var w=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var j=Object.prototype.hasOwnProperty;var C=(r,e)=>{for(var n in e)w(r,n,{get:e[n],enumerable:!0})},O=(r,e,n,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of T(e))!j.call(r,s)&&s!==n&&w(r,s,{get:()=>e[s],enumerable:!(t=S(e,s))||t.enumerable});return r};var B=r=>O(w({},"__esModule",{value:!0}),r);var H={};C(H,{Client:()=>l,Environment:()=>P,createDepositTxn:()=>y,fetchUserDepositHistory:()=>b,getRpcUrl:()=>x,useDeposit:()=>A});module.exports=B(H);var v=require("@solana/web3.js");var p=require("@solana/web3.js");var{NODE_ENV:F}=process.env,g=F==="development"?"http://localhost:5040":"https://storacha-solana-sdk-bshc.onrender.com";async function y({file:r,duration:e,payer:n,connection:t,signTransaction:s}){try{let o=new FormData;o.append("file",r),o.append("duration",e.toString()),o.append("publicKey",n.toBase58());let D,U=await fetch(`${g}/api/solana/deposit`,{method:"POST",body:o});if(!U.ok)throw new Error("Failed to get deposit instructions");let i=await U.json();if(!i.instructions||!i.instructions.length)throw new Error("No instructions from deposit API");let d=await t.getLatestBlockhash("confirmed"),f=i.instructions[0],I=new p.TransactionInstruction({programId:new p.PublicKey(f.programId),keys:f.keys.map(c=>({pubkey:new p.PublicKey(c.pubkey),isSigner:c.isSigner,isWritable:c.isWritable})),data:Buffer.from(f.data,"base64")}),m=new p.Transaction;m.recentBlockhash=d.blockhash,m.feePayer=n,m.add(I);let R=await s(m),E=await t.sendRawTransaction(R.serialize(),{skipPreflight:!1,preflightCommitment:"confirmed"}),u=await t.confirmTransaction({signature:E,blockhash:d.blockhash,lastValidBlockHeight:d.lastValidBlockHeight},"confirmed");if(u.value.err)throw console.error("Failed to confirm this transaction:",u.value.err),new Error(`Transaction failed: ${JSON.stringify(u.value.err)}`);i.error&&(D=i.error),new FormData().append("file",r);let h=await fetch(`${g}/api/user/uploadFile?cid=${encodeURIComponent(i.cid)}`,{method:"POST",body:o});if(!h.ok){let c="Unknown error";try{let k=await h.json();c=k.message||k.error||c}catch{}throw new Error("Deposit API error: "+c)}let a=await h.json();return{signature:E,success:!0,cid:i.cid,url:a.object.url,message:a.object.message,fileInfo:a.object?{filename:a.object.fileInfo?.filename||"",size:a?.object?.fileInfo?.size||0,uploadedAt:a?.object?.fileInfo?.uploadedAt||"",type:a?.object?.fileInfo?.type||""}:void 0}}catch(o){return console.error(o),o instanceof Error&&(console.error("Error name:",o.name),console.error("Error message:",o.message),console.error("Error stack:",o.stack)),{signature:"",success:!1,cid:"",url:"",message:"",fileInfo:void 0,error:o instanceof Error?o.message:"Unknown error occurred"}}}async function b(r,e={}){if(!r||typeof r!="string")throw new Error("User address is required and must be a string");let n=e.url||"http://localhost:3000";try{let t=await fetch(`${n}/getUserUploadHistory?userAddress=${encodeURIComponent(r)}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!t.ok){let o=await t.json().catch(()=>({}));throw new Error(o.message||`Failed to fetch deposit history: ${t.status} ${t.statusText}`)}let s=await t.json();if(typeof s!="object"||s===null)throw new Error("Invalid response format from server");if(typeof s.userAddress!="string")throw new Error("Invalid userAddress in response");return s}catch(t){throw t instanceof Error?t:new Error("Unknown error occurred while fetching deposit history")}}var P=(t=>(t.mainnet="mainnet-beta",t.testnet="testnet",t.devnet="devnet",t))(P||{});function x(r){switch(r){case"mainnet-beta":return"https://api.mainnet-beta.solana.com";case"testnet":return"https://api.testnet.solana.com";case"devnet":return"https://api.devnet.solana.com";default:throw new Error(`Unsupported environment: ${r}`)}}var l=class{constructor(e){this.estimateStorageCost=(e,n)=>{let o=e.size*n*1e3;return{sol:o/1e9,lamports:o}};this.rpcUrl=x(e.environment)}async createDeposit({payer:e,file:n,durationDays:t,signTransaction:s}){console.log("Creating deposit transaction with environment:",this.rpcUrl);let o=new v.Connection(this.rpcUrl,"confirmed");return await y({file:n,duration:t*86400,payer:e,connection:o,signTransaction:s})}async getUserUploadHistory(e){return await b(e)}};var A=r=>new l({environment:r||"testnet"});0&&(module.exports={Client,Environment,createDepositTxn,fetchUserDepositHistory,getRpcUrl,useDeposit});
1
+ "use strict";var I=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var $=Object.prototype.hasOwnProperty;var A=(r,e)=>{for(var n in e)I(r,n,{get:e[n],enumerable:!0})},B=(r,e,n,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of N(e))!$.call(r,s)&&s!==n&&I(r,s,{get:()=>e[s],enumerable:!(t=j(e,s))||t.enumerable});return r};var F=r=>B(I({},"__esModule",{value:!0}),r);var z={};A(z,{Client:()=>f,Environment:()=>x,createDepositTxn:()=>U,fetchUserDepositHistory:()=>P,getRpcUrl:()=>O,useDeposit:()=>H});module.exports=F(z);var T=require("@solana/web3.js");var{NODE_ENV:_}=process.env,l=_==="development"?"http://localhost:5040":"https://storacha-solana-sdk-bshc.onrender.com",v=86400;async function P(r,e={}){if(!r||typeof r!="string")throw new Error("User address is required and must be a string");let n=e.url||l;try{let t=await fetch(`${n}/api/user/user-upload-history?userAddress=${encodeURIComponent(r)}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!t.ok){let a=await t.json().catch(()=>({}));throw new Error(a.message||`Failed to fetch deposit history: ${t.status} ${t.statusText}`)}let s=await t.json();if(typeof s!="object"||s===null)throw new Error("Invalid response format from server");if(typeof s.userAddress!="string")throw new Error("Invalid userAddress in response");return s}catch(t){throw t instanceof Error?t:new Error("Unknown error occurred while fetching deposit history")}}var d=require("@solana/web3.js");async function U({file:r,duration:e,payer:n,connection:t,signTransaction:s,userEmail:a}){try{let o=new FormData;r.forEach(i=>o.append("file",i)),o.append("duration",e.toString()),o.append("publicKey",n.toBase58()),a&&o.append("userEmail",a);let h=r.length>1,w,S=await fetch(`${l}/api/solana/deposit`,{method:"POST",body:o});if(!S.ok)throw new Error("Failed to get deposit instructions");let c=await S.json();if(!c.instructions||!c.instructions.length)throw new Error("No instructions from deposit API");let g=await t.getLatestBlockhash("confirmed"),y=c.instructions[0],R=new d.TransactionInstruction({programId:new d.PublicKey(y.programId),keys:y.keys.map(i=>({pubkey:new d.PublicKey(i.pubkey),isSigner:i.isSigner,isWritable:i.isWritable})),data:Buffer.from(y.data,"base64")}),u=new d.Transaction;u.recentBlockhash=g.blockhash,u.feePayer=n,u.add(R);let C=await s(u),D=await t.sendRawTransaction(C.serialize(),{skipPreflight:!1,preflightCommitment:"confirmed"}),b=await t.confirmTransaction({signature:D,blockhash:g.blockhash,lastValidBlockHeight:g.lastValidBlockHeight},"confirmed");if(b.value.err)throw console.error("Failed to confirm this transaction:",b.value.err),new Error(`Transaction failed: ${JSON.stringify(b.value.err)}`);try{await fetch(`${l}/api/user/update-transaction-hash`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cid:c.cid,transactionHash:D})})}catch(i){console.warn("Failed to update transaction hash:",i)}c.error&&(w=c.error);let E=new FormData;r.forEach(i=>E.append("file",i));let m;if(h?m=await fetch(`${l}/api/user/upload-files?cid=${encodeURIComponent(c.cid)}`,{method:"POST",body:E}):m=await fetch(`${l}/api/user/upload-file?cid=${encodeURIComponent(c.cid)}`,{method:"POST",body:E}),!m.ok){let i="Unknown error";try{let k=await m.json();i=k.message||k.error||i}catch{}throw new Error("Deposit API error: "+i)}let p=await m?.json();return{signature:D,success:!0,cid:c.cid,url:p.object.url,message:p.object.message,fileInfo:p.object?{filename:p.object.fileInfo?.filename||"",size:p?.object?.fileInfo?.size||0,uploadedAt:p?.object?.fileInfo?.uploadedAt||"",type:p?.object?.fileInfo?.type||""}:void 0}}catch(o){return console.error(o),o instanceof Error&&(console.error("Error name:",o.name),console.error("Error message:",o.message),console.error("Error stack:",o.stack)),{signature:"",success:!1,cid:"",url:"",message:"",fileInfo:void 0,error:o instanceof Error?o.message:"Unknown error occurred"}}}var x=(t=>(t.mainnet="mainnet-beta",t.testnet="testnet",t.devnet="devnet",t))(x||{});function O(r){switch(r){case"mainnet-beta":return"https://api.mainnet-beta.solana.com";case"testnet":return"https://api.testnet.solana.com";case"devnet":return"https://api.devnet.solana.com";default:throw new Error(`Unsupported environment: ${r}`)}}var f=class{constructor(e){this.estimateStorageCost=(e,n)=>{let a=e.reduce((h,w)=>h+w.size,0)*n*1e3;return{sol:a/1e9,lamports:a}};this.rpcUrl=O(e.environment)}async createDeposit({payer:e,file:n,durationDays:t,signTransaction:s,userEmail:a}){console.log("Creating deposit transaction with environment:",this.rpcUrl);let o=new T.Connection(this.rpcUrl,"confirmed");return await U({file:n,duration:t*v,payer:e,connection:o,signTransaction:s,userEmail:a})}async getUserUploadHistory(e){return await P(e)}};var H=r=>new f({environment:r||"testnet"});0&&(module.exports={Client,Environment,createDepositTxn,fetchUserDepositHistory,getRpcUrl,useDeposit});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/payment.ts","../src/constants.ts","../src/depositHistory.ts","../src/hooks.ts"],"sourcesContent":["export * from \"./client\"\nexport * from \"./types\"\nexport * from \"./payment\"\nexport * from \"./hooks\"\nexport * from \"./depositHistory\"\n","import { PublicKey, Connection } from '@solana/web3.js';\nimport { createDepositTxn } from './payment';\nimport { CreateDepositArgs, UploadResult } from './types';\nimport { fetchUserDepositHistory } from './depositHistory';\n\nexport enum Environment {\n mainnet = 'mainnet-beta',\n testnet = 'testnet',\n devnet = 'devnet',\n}\n\nexport function getRpcUrl(env: Environment): string {\n switch (env) {\n case Environment.mainnet:\n return 'https://api.mainnet-beta.solana.com';\n case Environment.testnet:\n return 'https://api.testnet.solana.com';\n case Environment.devnet:\n return 'https://api.devnet.solana.com';\n default:\n throw new Error(`Unsupported environment: ${env}`);\n }\n}\n\nexport interface ClientOptions {\n /** Solana RPC endpoint to use for chain interactions */\n environment: Environment;\n}\n\nexport interface DepositParams\n extends Pick<CreateDepositArgs, 'signTransaction'> {\n /** Wallet public key of the payer */\n payer: PublicKey;\n /** File to be stored */\n file: File;\n /** Duration in days to store the data */\n durationDays: number;\n}\n\n/**\n * Solana Storage Client — simplified (no fee estimation)\n */\nexport class Client {\n private rpcUrl: string;\n\n constructor(options: ClientOptions) {\n this.rpcUrl = getRpcUrl(options.environment);\n }\n\n /**\n * Creates a deposit transaction ready to be signed & sent by user's wallet.\n *\n * @param {Object} params\n * @param {PublicKey} params.payer - The public key (wallet address) of the connected wallet.\n * @param {File} params.file - The file to be uploaded.\n * @param {number} params.durationDays - How long (in days) the file should be stored.\n * @param {(tx: Transaction) => Promise<Transaction>} params.signTransaction -\n * A callback function to authorize the transaction via the Solana wallet library.\n *\n * @example\n * const { publicKey, signTransaction } = useSolanaWallet();\n * const result = await createDeposit({\n * payer: publicKey,\n * file,\n * durationDays: 30,\n * signTransaction,\n * });\n *\n * @returns {Promise<UploadResult>} The upload result after transaction is processed.\n */\n async createDeposit({\n payer,\n file,\n durationDays,\n signTransaction,\n }: DepositParams): Promise<UploadResult> {\n console.log('Creating deposit transaction with environment:', this.rpcUrl);\n const connection = new Connection(this.rpcUrl, 'confirmed');\n\n return await createDepositTxn({\n file,\n duration: durationDays * 86400,\n payer,\n connection,\n signTransaction,\n });\n }\n\n /**\n * estimates the cost for a file based on the amount of days it should be stored for\n * @param {File} file - a file to be uploaded\n * @param {number} duration - how long (in seconds) the file should be stored for\n */\n estimateStorageCost = (file: File, duration: number) => {\n const ratePerBytePerDay = 1000; // this would be obtained from the program config later\n const fileSizeInBytes = file.size;\n const totalLamports = fileSizeInBytes * duration * ratePerBytePerDay;\n const totalSOL = totalLamports / 1_000_000_000;\n\n return {\n sol: totalSOL,\n lamports: totalLamports,\n };\n };\n\n async getUserUploadHistory(userAddress: string) {\n const response = await fetchUserDepositHistory(userAddress);\n return response\n }\n}\n","import { Signature } from '@solana/kit';\nimport { CreateDepositArgs, DepositResult, UploadResult } from './types';\nimport {\n PublicKey,\n Transaction,\n TransactionInstruction,\n} from '@solana/web3.js';\nimport { ENDPOINT } from './constants';\n\n/**\n * Calls the deposit API for on-chain storage and returns a Transaction\n * which must be signed and sent externally by the user.\n *\n * @param params - {\n * cid: string;\n * file: File;\n * duration: number;\n * payer: PublicKey;\n * connection: Connection;\n * }\n * @returns Transaction\n */\nexport async function createDepositTxn({\n file,\n duration,\n payer,\n connection,\n signTransaction,\n}: CreateDepositArgs): Promise<UploadResult> {\n try {\n const formData = new FormData();\n formData.append('file', file);\n formData.append('duration', duration.toString());\n formData.append('publicKey', payer.toBase58());\n\n let uploadErr;\n\n const depositReq = await fetch(`${ENDPOINT}/api/solana/deposit`, {\n method: 'POST',\n body: formData,\n });\n if (!depositReq.ok) throw new Error('Failed to get deposit instructions');\n\n const depositRes: DepositResult = await depositReq.json();\n if (!depositRes.instructions || !depositRes.instructions.length)\n throw new Error('No instructions from deposit API');\n\n const latestBlockhash = await connection.getLatestBlockhash('confirmed');\n const instructions = depositRes.instructions[0];\n\n const depositInstruction = new TransactionInstruction({\n programId: new PublicKey(instructions.programId),\n keys: instructions.keys.map((k) => ({\n pubkey: new PublicKey(k.pubkey),\n isSigner: k.isSigner,\n isWritable: k.isWritable,\n })),\n data: Buffer.from(instructions.data, 'base64'),\n });\n\n const tx = new Transaction();\n tx.recentBlockhash = latestBlockhash.blockhash;\n tx.feePayer = payer;\n tx.add(depositInstruction);\n\n const signedTx = await signTransaction(tx);\n const signature = await connection.sendRawTransaction(\n signedTx.serialize(),\n {\n skipPreflight: false, // not sure we should be disabling this verification step\n preflightCommitment: 'confirmed',\n }\n );\n const confirmation = await connection.confirmTransaction(\n {\n signature,\n blockhash: latestBlockhash.blockhash,\n lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,\n },\n 'confirmed'\n );\n\n if (confirmation.value.err) {\n console.error(\n 'Failed to confirm this transaction:',\n confirmation.value.err\n );\n throw new Error(\n `Transaction failed: ${JSON.stringify(confirmation.value.err)}`\n );\n }\n\n if (depositRes.error) {\n uploadErr = depositRes.error;\n }\n\n const uploadForm = new FormData();\n uploadForm.append('file', file);\n\n // calls the upload functionality on our server with the file when deposit is succesful\n const fileUploadReq = await fetch(\n `${ENDPOINT}/api/user/uploadFile?cid=${encodeURIComponent(depositRes.cid)}`,\n {\n method: 'POST',\n body: formData,\n }\n );\n\n if (!fileUploadReq.ok) {\n let err = 'Unknown error';\n try {\n const data: DepositResult = await fileUploadReq.json();\n err = data.message || data.error || err;\n } catch {}\n throw new Error('Deposit API error: ' + err);\n }\n\n const fileUploadRes: Pick<DepositResult, 'object' | 'cid' | 'message'> =\n await fileUploadReq.json();\n\n return {\n signature: signature as Signature,\n success: true,\n cid: depositRes.cid,\n url: fileUploadRes.object.url,\n message: fileUploadRes.object.message,\n fileInfo: fileUploadRes.object\n ? {\n filename: fileUploadRes.object.fileInfo?.filename || '',\n size: fileUploadRes?.object?.fileInfo?.size || 0,\n uploadedAt: fileUploadRes?.object?.fileInfo?.uploadedAt || '',\n type: fileUploadRes?.object?.fileInfo?.type || '',\n }\n : undefined,\n };\n } catch (error) {\n console.error(error);\n if (error instanceof Error) {\n console.error('Error name:', error.name);\n console.error('Error message:', error.message);\n console.error('Error stack:', error.stack);\n }\n\n return {\n signature: '' as Signature,\n success: false,\n cid: '',\n url: '',\n message: '',\n fileInfo: undefined,\n error: error instanceof Error ? error.message : 'Unknown error occurred',\n };\n }\n}\n","const { NODE_ENV } = process.env;\n\nexport const ENDPOINT =\n NODE_ENV === 'development'\n ? 'http://localhost:5040'\n : 'https://storacha-solana-sdk-bshc.onrender.com';\n","import { DepositHistoryResponse, ServerOptions } from './types';\n\n/**\n * Fetches the deposit history for a given user address from the backend\n * \n * @param userAddress - The wallet address of the user to fetch deposit history for\n * @param options - Optional server configuration\n * @returns Promise<DepositHistoryResponse> - The user's deposit history\n * \n * @example\n * ```typescript\n * const history = await fetchUserDepositHistory('9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM');\n * console.log('User deposit history:', history.userHistory);\n * ```\n * \n * @throws {Error} When the user address is invalid or the request fails\n */\nexport async function fetchUserDepositHistory(\n userAddress: string,\n options: ServerOptions = {}\n): Promise<DepositHistoryResponse> {\n // Validate user address\n if (!userAddress || typeof userAddress !== 'string') {\n throw new Error('User address is required and must be a string');\n }\n\n // Default backend URL - can be overridden via options\n const baseUrl = options.url || 'http://localhost:3000';\n \n try {\n const response = await fetch(\n `${baseUrl}/getUserUploadHistory?userAddress=${encodeURIComponent(userAddress)}`,\n {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(\n errorData.message || \n `Failed to fetch deposit history: ${response.status} ${response.statusText}`\n );\n }\n\n const data: DepositHistoryResponse = await response.json();\n \n // Validate response structure\n if (typeof data !== 'object' || data === null) {\n throw new Error('Invalid response format from server');\n }\n\n if (typeof data.userAddress !== 'string') {\n throw new Error('Invalid userAddress in response');\n }\n\n return data;\n } catch (error) {\n if (error instanceof Error) {\n throw error;\n }\n throw new Error('Unknown error occurred while fetching deposit history');\n }\n}\n","import { Client, ClientOptions } from './client';\n\nexport const useDeposit = (environment: ClientOptions['environment']) => {\n const client = new Client({ environment: environment || 'testnet' });\n return client;\n};\n"],"mappings":"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","names":["index_exports","__export","Client","Environment","createDepositTxn","fetchUserDepositHistory","getRpcUrl","useDeposit","__toCommonJS","import_web3","import_web3","NODE_ENV","ENDPOINT","createDepositTxn","file","duration","payer","connection","signTransaction","formData","uploadErr","depositReq","ENDPOINT","depositRes","latestBlockhash","instructions","depositInstruction","k","tx","signedTx","signature","confirmation","fileUploadReq","err","data","fileUploadRes","error","fetchUserDepositHistory","userAddress","options","baseUrl","response","errorData","data","error","Environment","getRpcUrl","env","Client","options","file","duration","totalLamports","payer","durationDays","signTransaction","connection","createDepositTxn","userAddress","fetchUserDepositHistory","useDeposit","environment","Client"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/constants.ts","../src/depositHistory.ts","../src/payment.ts","../src/hooks.ts"],"sourcesContent":["export * from \"./client\"\nexport * from \"./types\"\nexport * from \"./payment\"\nexport * from \"./hooks\"\nexport * from \"./depositHistory\"\n","import { Connection, PublicKey } from '@solana/web3.js';\nimport { DAY_TIME_IN_SECONDS } from './constants';\nimport { fetchUserDepositHistory } from './depositHistory';\nimport { createDepositTxn } from './payment';\nimport { CreateDepositArgs, UploadResult } from './types';\n\nexport enum Environment {\n mainnet = 'mainnet-beta',\n testnet = 'testnet',\n devnet = 'devnet',\n}\n\nexport function getRpcUrl(env: Environment): string {\n switch (env) {\n case Environment.mainnet:\n return 'https://api.mainnet-beta.solana.com';\n case Environment.testnet:\n return 'https://api.testnet.solana.com';\n case Environment.devnet:\n return 'https://api.devnet.solana.com';\n default:\n throw new Error(`Unsupported environment: ${env}`);\n }\n}\n\nexport interface ClientOptions {\n /** Solana RPC endpoint to use for chain interactions */\n environment: Environment;\n}\n\nexport interface DepositParams\n extends Pick<CreateDepositArgs, 'signTransaction' | 'userEmail'> {\n /** Wallet public key of the payer */\n payer: PublicKey;\n /** File(s) to be stored */\n file: File[];\n /** Duration in days to store the data */\n durationDays: number;\n}\n\n/**\n * Solana Storage Client — simplified (no fee estimation)\n */\nexport class Client {\n private rpcUrl: string;\n\n constructor(options: ClientOptions) {\n this.rpcUrl = getRpcUrl(options.environment);\n }\n\n /**\n * Creates a deposit transaction ready to be signed & sent by user's wallet.\n *\n * @param {Object} params\n * @param {PublicKey} params.payer - The public key (wallet address) of the connected wallet.\n * @param {File} params.file - The file to be uploaded.\n * @param {number} params.durationDays - How long (in days) the file should be stored.\n * @param {(tx: Transaction) => Promise<Transaction>} params.signTransaction -\n * A callback function to authorize the transaction via the Solana wallet library.\n *\n * @example\n * const { publicKey, signTransaction } = useSolanaWallet();\n * const result = await createDeposit({\n * payer: publicKey,\n * file,\n * durationDays: 30,\n * signTransaction,\n * });\n *\n * @returns {Promise<UploadResult>} The upload result after transaction is processed.\n */\n async createDeposit({\n payer,\n file,\n durationDays,\n signTransaction,\n userEmail,\n }: DepositParams): Promise<UploadResult> {\n console.log('Creating deposit transaction with environment:', this.rpcUrl);\n const connection = new Connection(this.rpcUrl, 'confirmed');\n\n return await createDepositTxn({\n file,\n duration: durationDays * DAY_TIME_IN_SECONDS,\n payer,\n connection,\n signTransaction,\n userEmail,\n });\n }\n\n /**\n * estimates the cost for a file based on the amount of days it should be stored for\n * @param {File} file - a file to be uploaded\n * @param {number} duration - how long (in seconds) the file should be stored for\n */\n estimateStorageCost = (file: File[], duration: number) => {\n const ratePerBytePerDay = 1000; // this would be obtained from the program config later\n const fileSizeInBytes = file.reduce((acc, f) => acc + f.size, 0);\n const totalLamports = fileSizeInBytes * duration * ratePerBytePerDay;\n const totalSOL = totalLamports / 1_000_000_000;\n\n return {\n sol: totalSOL,\n lamports: totalLamports,\n };\n };\n\n async getUserUploadHistory(userAddress: string) {\n const response = await fetchUserDepositHistory(userAddress);\n return response;\n }\n}\n","const { NODE_ENV } = process.env;\n\nexport const ENDPOINT =\n NODE_ENV === 'development'\n ? 'http://localhost:5040'\n : 'https://storacha-solana-sdk-bshc.onrender.com';\n\nexport const DAY_TIME_IN_SECONDS = 86400;\n","import { ENDPOINT } from './constants';\nimport { DepositHistoryResponse, ServerOptions } from './types';\n\n/**\n * Fetches the deposit history for a given user address from the backend\n *\n * @param userAddress - The wallet address of the user to fetch deposit history for\n * @param options - Optional server configuration\n * @returns Promise<DepositHistoryResponse> - The user's deposit history\n *\n * @example\n * ```typescript\n * const history = await fetchUserDepositHistory('9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM');\n * console.log('User deposit history:', history.userHistory);\n * ```\n *\n * @throws {Error} When the user address is invalid or the request fails\n */\nexport async function fetchUserDepositHistory(\n userAddress: string,\n options: ServerOptions = {}\n): Promise<DepositHistoryResponse> {\n // Validate user address\n if (!userAddress || typeof userAddress !== 'string') {\n throw new Error('User address is required and must be a string');\n }\n\n // Use ENDPOINT constant, or allow override via options\n const baseUrl = options.url || ENDPOINT;\n\n try {\n const response = await fetch(\n `${baseUrl}/api/user/user-upload-history?userAddress=${encodeURIComponent(userAddress)}`,\n {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(\n errorData.message ||\n `Failed to fetch deposit history: ${response.status} ${response.statusText}`\n );\n }\n\n const data: DepositHistoryResponse = await response.json();\n\n // Validate response structure\n if (typeof data !== 'object' || data === null) {\n throw new Error('Invalid response format from server');\n }\n\n if (typeof data.userAddress !== 'string') {\n throw new Error('Invalid userAddress in response');\n }\n\n return data;\n } catch (error) {\n if (error instanceof Error) {\n throw error;\n }\n throw new Error('Unknown error occurred while fetching deposit history');\n }\n}\n","import { Signature } from '@solana/kit';\nimport {\n PublicKey,\n Transaction,\n TransactionInstruction,\n} from '@solana/web3.js';\nimport { ENDPOINT } from './constants';\nimport { CreateDepositArgs, DepositResult, UploadResult } from './types';\n\n/**\n * Calls the deposit API for on-chain storage and returns a Transaction\n * which must be signed and sent externally by the user.\n *\n * @param params - {\n * cid: string;\n * file: File;\n * duration: number;\n * payer: PublicKey;\n * connection: Connection;\n * }\n * @returns Transaction\n */\nexport async function createDepositTxn({\n file,\n duration,\n payer,\n connection,\n signTransaction,\n userEmail,\n}: CreateDepositArgs): Promise<UploadResult> {\n try {\n const formData = new FormData();\n file.forEach((f) => formData.append('file', f));\n formData.append('duration', duration.toString());\n formData.append('publicKey', payer.toBase58());\n if (userEmail) {\n formData.append('userEmail', userEmail);\n }\n\n const isMultipleFiles = file.length > 1;\n\n let uploadErr;\n\n const depositReq = await fetch(`${ENDPOINT}/api/solana/deposit`, {\n method: 'POST',\n body: formData,\n });\n if (!depositReq.ok) throw new Error('Failed to get deposit instructions');\n\n const depositRes: DepositResult = await depositReq.json();\n if (!depositRes.instructions || !depositRes.instructions.length)\n throw new Error('No instructions from deposit API');\n\n const latestBlockhash = await connection.getLatestBlockhash('confirmed');\n const instructions = depositRes.instructions[0];\n\n const depositInstruction = new TransactionInstruction({\n programId: new PublicKey(instructions.programId),\n keys: instructions.keys.map((k) => ({\n pubkey: new PublicKey(k.pubkey),\n isSigner: k.isSigner,\n isWritable: k.isWritable,\n })),\n data: Buffer.from(instructions.data, 'base64'),\n });\n\n const tx = new Transaction();\n tx.recentBlockhash = latestBlockhash.blockhash;\n tx.feePayer = payer;\n tx.add(depositInstruction);\n\n const signedTx = await signTransaction(tx);\n const signature = await connection.sendRawTransaction(\n signedTx.serialize(),\n {\n skipPreflight: false, // not sure we should be disabling this verification step\n preflightCommitment: 'confirmed',\n }\n );\n const confirmation = await connection.confirmTransaction(\n {\n signature,\n blockhash: latestBlockhash.blockhash,\n lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,\n },\n 'confirmed'\n );\n\n if (confirmation.value.err) {\n console.error(\n 'Failed to confirm this transaction:',\n confirmation.value.err\n );\n throw new Error(\n `Transaction failed: ${JSON.stringify(confirmation.value.err)}`\n );\n }\n\n try {\n await fetch(`${ENDPOINT}/api/user/update-transaction-hash`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n cid: depositRes.cid,\n transactionHash: signature,\n }),\n });\n } catch (err) {\n console.warn('Failed to update transaction hash:', err);\n }\n\n if (depositRes.error) {\n uploadErr = depositRes.error;\n }\n\n const uploadForm = new FormData();\n file.forEach((f) => uploadForm.append('file', f));\n\n let fileUploadReq;\n // calls the upload functionality on our server with the file when deposit is succesful\n if (isMultipleFiles) {\n fileUploadReq = await fetch(\n `${ENDPOINT}/api/user/upload-files?cid=${encodeURIComponent(depositRes.cid)}`,\n {\n method: 'POST',\n body: uploadForm,\n }\n );\n } else {\n fileUploadReq = await fetch(\n `${ENDPOINT}/api/user/upload-file?cid=${encodeURIComponent(depositRes.cid)}`,\n {\n method: 'POST',\n body: uploadForm,\n }\n );\n }\n\n if (!fileUploadReq.ok) {\n let err = 'Unknown error';\n try {\n const data: DepositResult = await fileUploadReq.json();\n err = data.message || data.error || err;\n } catch {}\n throw new Error('Deposit API error: ' + err);\n }\n\n const fileUploadRes: Pick<DepositResult, 'object' | 'cid' | 'message'> =\n await fileUploadReq?.json();\n\n return {\n signature: signature as Signature,\n success: true,\n cid: depositRes.cid,\n url: fileUploadRes.object.url,\n message: fileUploadRes.object.message,\n fileInfo: fileUploadRes.object\n ? {\n filename: fileUploadRes.object.fileInfo?.filename || '',\n size: fileUploadRes?.object?.fileInfo?.size || 0,\n uploadedAt: fileUploadRes?.object?.fileInfo?.uploadedAt || '',\n type: fileUploadRes?.object?.fileInfo?.type || '',\n }\n : undefined,\n };\n } catch (error) {\n console.error(error);\n if (error instanceof Error) {\n console.error('Error name:', error.name);\n console.error('Error message:', error.message);\n console.error('Error stack:', error.stack);\n }\n\n return {\n signature: '' as Signature,\n success: false,\n cid: '',\n url: '',\n message: '',\n fileInfo: undefined,\n error: error instanceof Error ? error.message : 'Unknown error occurred',\n };\n }\n}\n","import { Client, ClientOptions } from './client';\n\nexport const useDeposit = (environment: ClientOptions['environment']) => {\n const client = new Client({ environment: environment || 'testnet' });\n return client;\n};\n"],"mappings":"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","names":["index_exports","__export","Client","Environment","createDepositTxn","fetchUserDepositHistory","getRpcUrl","useDeposit","__toCommonJS","import_web3","NODE_ENV","ENDPOINT","DAY_TIME_IN_SECONDS","fetchUserDepositHistory","userAddress","options","baseUrl","ENDPOINT","response","errorData","data","error","import_web3","createDepositTxn","file","duration","payer","connection","signTransaction","userEmail","formData","f","isMultipleFiles","uploadErr","depositReq","ENDPOINT","depositRes","latestBlockhash","instructions","depositInstruction","k","tx","signedTx","signature","confirmation","err","uploadForm","fileUploadReq","data","fileUploadRes","error","Environment","getRpcUrl","env","Client","options","file","duration","totalLamports","acc","f","payer","durationDays","signTransaction","userEmail","connection","createDepositTxn","DAY_TIME_IN_SECONDS","userAddress","fetchUserDepositHistory","useDeposit","environment","Client"]}
package/dist/index.d.cts CHANGED
@@ -79,7 +79,7 @@ interface OnChainDeposit {
79
79
  /** public key of the depositor */
80
80
  depositor: Address;
81
81
  /** file object containing metadata about the upload */
82
- file: File;
82
+ file: File[];
83
83
  /** storage duration (days) */
84
84
  duration: number;
85
85
  /** amount deposited in lamports */
@@ -117,6 +117,8 @@ interface CreateDepositArgs extends Omit<OnChainDeposit, 'depositAmount' | 'depo
117
117
  * const signTransaction = await signTransaction(tx)
118
118
  * */
119
119
  signTransaction: (tx: Transaction) => Promise<Transaction>;
120
+ /** Optional user email for expiration notifications */
121
+ userEmail?: string;
120
122
  }
121
123
  /**
122
124
  * Individual deposit history entry from the backend
@@ -125,19 +127,35 @@ interface DepositHistoryEntry {
125
127
  /** Unique identifier for the deposit */
126
128
  id: number;
127
129
  /** User's wallet address (deposit key) */
128
- deposit_key: string;
130
+ depositKey: string;
129
131
  /** Content identifier of the uploaded file */
130
- content_cid: string;
132
+ contentCid: string;
131
133
  /** Duration in days the file is stored for */
132
- duration_days: number;
134
+ durationDays: number;
133
135
  /** Amount deposited in lamports */
134
- deposit_amount: number;
136
+ depositAmount: number;
135
137
  /** Slot when the deposit was made */
136
- deposit_slot: number;
138
+ depositSlot: number;
137
139
  /** Last slot when rewards were claimed */
138
- last_claimed_slot: number;
140
+ lastClaimedSlot: number;
139
141
  /** Timestamp when the deposit was created */
140
- created_at: string;
142
+ createdAt: string;
143
+ /** Expiration date of the upload */
144
+ expiresAt?: string;
145
+ /** User email for notifications */
146
+ userEmail?: string;
147
+ /** Name of the uploaded file */
148
+ fileName?: string;
149
+ /** MIME type of the file */
150
+ fileType?: string;
151
+ /** Size of the file in bytes */
152
+ fileSize?: number;
153
+ /** Solana transaction hash */
154
+ transactionHash?: string;
155
+ /** Deletion status: 'active' | 'warned' | 'deleted' */
156
+ deletionStatus?: string;
157
+ /** Timestamp when warning email was sent */
158
+ warningSentAt?: string;
141
159
  }
142
160
  /**
143
161
  * Response from the getUserUploadHistory endpoint
@@ -159,11 +177,11 @@ interface ClientOptions {
159
177
  /** Solana RPC endpoint to use for chain interactions */
160
178
  environment: Environment;
161
179
  }
162
- interface DepositParams extends Pick<CreateDepositArgs, 'signTransaction'> {
180
+ interface DepositParams extends Pick<CreateDepositArgs, 'signTransaction' | 'userEmail'> {
163
181
  /** Wallet public key of the payer */
164
182
  payer: PublicKey;
165
- /** File to be stored */
166
- file: File;
183
+ /** File(s) to be stored */
184
+ file: File[];
167
185
  /** Duration in days to store the data */
168
186
  durationDays: number;
169
187
  }
@@ -194,13 +212,13 @@ declare class Client {
194
212
  *
195
213
  * @returns {Promise<UploadResult>} The upload result after transaction is processed.
196
214
  */
197
- createDeposit({ payer, file, durationDays, signTransaction, }: DepositParams): Promise<UploadResult>;
215
+ createDeposit({ payer, file, durationDays, signTransaction, userEmail, }: DepositParams): Promise<UploadResult>;
198
216
  /**
199
217
  * estimates the cost for a file based on the amount of days it should be stored for
200
218
  * @param {File} file - a file to be uploaded
201
219
  * @param {number} duration - how long (in seconds) the file should be stored for
202
220
  */
203
- estimateStorageCost: (file: File, duration: number) => {
221
+ estimateStorageCost: (file: File[], duration: number) => {
204
222
  sol: number;
205
223
  lamports: number;
206
224
  };
@@ -220,7 +238,7 @@ declare class Client {
220
238
  * }
221
239
  * @returns Transaction
222
240
  */
223
- declare function createDepositTxn({ file, duration, payer, connection, signTransaction, }: CreateDepositArgs): Promise<UploadResult>;
241
+ declare function createDepositTxn({ file, duration, payer, connection, signTransaction, userEmail, }: CreateDepositArgs): Promise<UploadResult>;
224
242
 
225
243
  declare const useDeposit: (environment: ClientOptions["environment"]) => Client;
226
244
 
package/dist/index.d.ts CHANGED
@@ -79,7 +79,7 @@ interface OnChainDeposit {
79
79
  /** public key of the depositor */
80
80
  depositor: Address;
81
81
  /** file object containing metadata about the upload */
82
- file: File;
82
+ file: File[];
83
83
  /** storage duration (days) */
84
84
  duration: number;
85
85
  /** amount deposited in lamports */
@@ -117,6 +117,8 @@ interface CreateDepositArgs extends Omit<OnChainDeposit, 'depositAmount' | 'depo
117
117
  * const signTransaction = await signTransaction(tx)
118
118
  * */
119
119
  signTransaction: (tx: Transaction) => Promise<Transaction>;
120
+ /** Optional user email for expiration notifications */
121
+ userEmail?: string;
120
122
  }
121
123
  /**
122
124
  * Individual deposit history entry from the backend
@@ -125,19 +127,35 @@ interface DepositHistoryEntry {
125
127
  /** Unique identifier for the deposit */
126
128
  id: number;
127
129
  /** User's wallet address (deposit key) */
128
- deposit_key: string;
130
+ depositKey: string;
129
131
  /** Content identifier of the uploaded file */
130
- content_cid: string;
132
+ contentCid: string;
131
133
  /** Duration in days the file is stored for */
132
- duration_days: number;
134
+ durationDays: number;
133
135
  /** Amount deposited in lamports */
134
- deposit_amount: number;
136
+ depositAmount: number;
135
137
  /** Slot when the deposit was made */
136
- deposit_slot: number;
138
+ depositSlot: number;
137
139
  /** Last slot when rewards were claimed */
138
- last_claimed_slot: number;
140
+ lastClaimedSlot: number;
139
141
  /** Timestamp when the deposit was created */
140
- created_at: string;
142
+ createdAt: string;
143
+ /** Expiration date of the upload */
144
+ expiresAt?: string;
145
+ /** User email for notifications */
146
+ userEmail?: string;
147
+ /** Name of the uploaded file */
148
+ fileName?: string;
149
+ /** MIME type of the file */
150
+ fileType?: string;
151
+ /** Size of the file in bytes */
152
+ fileSize?: number;
153
+ /** Solana transaction hash */
154
+ transactionHash?: string;
155
+ /** Deletion status: 'active' | 'warned' | 'deleted' */
156
+ deletionStatus?: string;
157
+ /** Timestamp when warning email was sent */
158
+ warningSentAt?: string;
141
159
  }
142
160
  /**
143
161
  * Response from the getUserUploadHistory endpoint
@@ -159,11 +177,11 @@ interface ClientOptions {
159
177
  /** Solana RPC endpoint to use for chain interactions */
160
178
  environment: Environment;
161
179
  }
162
- interface DepositParams extends Pick<CreateDepositArgs, 'signTransaction'> {
180
+ interface DepositParams extends Pick<CreateDepositArgs, 'signTransaction' | 'userEmail'> {
163
181
  /** Wallet public key of the payer */
164
182
  payer: PublicKey;
165
- /** File to be stored */
166
- file: File;
183
+ /** File(s) to be stored */
184
+ file: File[];
167
185
  /** Duration in days to store the data */
168
186
  durationDays: number;
169
187
  }
@@ -194,13 +212,13 @@ declare class Client {
194
212
  *
195
213
  * @returns {Promise<UploadResult>} The upload result after transaction is processed.
196
214
  */
197
- createDeposit({ payer, file, durationDays, signTransaction, }: DepositParams): Promise<UploadResult>;
215
+ createDeposit({ payer, file, durationDays, signTransaction, userEmail, }: DepositParams): Promise<UploadResult>;
198
216
  /**
199
217
  * estimates the cost for a file based on the amount of days it should be stored for
200
218
  * @param {File} file - a file to be uploaded
201
219
  * @param {number} duration - how long (in seconds) the file should be stored for
202
220
  */
203
- estimateStorageCost: (file: File, duration: number) => {
221
+ estimateStorageCost: (file: File[], duration: number) => {
204
222
  sol: number;
205
223
  lamports: number;
206
224
  };
@@ -220,7 +238,7 @@ declare class Client {
220
238
  * }
221
239
  * @returns Transaction
222
240
  */
223
- declare function createDepositTxn({ file, duration, payer, connection, signTransaction, }: CreateDepositArgs): Promise<UploadResult>;
241
+ declare function createDepositTxn({ file, duration, payer, connection, signTransaction, userEmail, }: CreateDepositArgs): Promise<UploadResult>;
224
242
 
225
243
  declare const useDeposit: (environment: ClientOptions["environment"]) => Client;
226
244
 
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{Connection as R}from"@solana/web3.js";import{PublicKey as D,Transaction as x,TransactionInstruction as I}from"@solana/web3.js";var{NODE_ENV:P}=process.env,h=P==="development"?"http://localhost:5040":"https://storacha-solana-sdk-bshc.onrender.com";async function U({file:r,duration:o,payer:s,connection:t,signTransaction:n}){try{let e=new FormData;e.append("file",r),e.append("duration",o.toString()),e.append("publicKey",s.toBase58());let w,g=await fetch(`${h}/api/solana/deposit`,{method:"POST",body:e});if(!g.ok)throw new Error("Failed to get deposit instructions");let i=await g.json();if(!i.instructions||!i.instructions.length)throw new Error("No instructions from deposit API");let m=await t.getLatestBlockhash("confirmed"),d=i.instructions[0],k=new I({programId:new D(d.programId),keys:d.keys.map(c=>({pubkey:new D(c.pubkey),isSigner:c.isSigner,isWritable:c.isWritable})),data:Buffer.from(d.data,"base64")}),p=new x;p.recentBlockhash=m.blockhash,p.feePayer=s,p.add(k);let v=await n(p),y=await t.sendRawTransaction(v.serialize(),{skipPreflight:!1,preflightCommitment:"confirmed"}),f=await t.confirmTransaction({signature:y,blockhash:m.blockhash,lastValidBlockHeight:m.lastValidBlockHeight},"confirmed");if(f.value.err)throw console.error("Failed to confirm this transaction:",f.value.err),new Error(`Transaction failed: ${JSON.stringify(f.value.err)}`);i.error&&(w=i.error),new FormData().append("file",r);let u=await fetch(`${h}/api/user/uploadFile?cid=${encodeURIComponent(i.cid)}`,{method:"POST",body:e});if(!u.ok){let c="Unknown error";try{let b=await u.json();c=b.message||b.error||c}catch{}throw new Error("Deposit API error: "+c)}let a=await u.json();return{signature:y,success:!0,cid:i.cid,url:a.object.url,message:a.object.message,fileInfo:a.object?{filename:a.object.fileInfo?.filename||"",size:a?.object?.fileInfo?.size||0,uploadedAt:a?.object?.fileInfo?.uploadedAt||"",type:a?.object?.fileInfo?.type||""}:void 0}}catch(e){return console.error(e),e instanceof Error&&(console.error("Error name:",e.name),console.error("Error message:",e.message),console.error("Error stack:",e.stack)),{signature:"",success:!1,cid:"",url:"",message:"",fileInfo:void 0,error:e instanceof Error?e.message:"Unknown error occurred"}}}async function E(r,o={}){if(!r||typeof r!="string")throw new Error("User address is required and must be a string");let s=o.url||"http://localhost:3000";try{let t=await fetch(`${s}/getUserUploadHistory?userAddress=${encodeURIComponent(r)}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!t.ok){let e=await t.json().catch(()=>({}));throw new Error(e.message||`Failed to fetch deposit history: ${t.status} ${t.statusText}`)}let n=await t.json();if(typeof n!="object"||n===null)throw new Error("Invalid response format from server");if(typeof n.userAddress!="string")throw new Error("Invalid userAddress in response");return n}catch(t){throw t instanceof Error?t:new Error("Unknown error occurred while fetching deposit history")}}var S=(t=>(t.mainnet="mainnet-beta",t.testnet="testnet",t.devnet="devnet",t))(S||{});function T(r){switch(r){case"mainnet-beta":return"https://api.mainnet-beta.solana.com";case"testnet":return"https://api.testnet.solana.com";case"devnet":return"https://api.devnet.solana.com";default:throw new Error(`Unsupported environment: ${r}`)}}var l=class{constructor(o){this.estimateStorageCost=(o,s)=>{let e=o.size*s*1e3;return{sol:e/1e9,lamports:e}};this.rpcUrl=T(o.environment)}async createDeposit({payer:o,file:s,durationDays:t,signTransaction:n}){console.log("Creating deposit transaction with environment:",this.rpcUrl);let e=new R(this.rpcUrl,"confirmed");return await U({file:s,duration:t*86400,payer:o,connection:e,signTransaction:n})}async getUserUploadHistory(o){return await E(o)}};var q=r=>new l({environment:r||"testnet"});export{l as Client,S as Environment,U as createDepositTxn,E as fetchUserDepositHistory,T as getRpcUrl,q as useDeposit};
1
+ import{Connection as C}from"@solana/web3.js";var{NODE_ENV:x}=process.env,l=x==="development"?"http://localhost:5040":"https://storacha-solana-sdk-bshc.onrender.com",P=86400;async function U(r,s={}){if(!r||typeof r!="string")throw new Error("User address is required and must be a string");let n=s.url||l;try{let e=await fetch(`${n}/api/user/user-upload-history?userAddress=${encodeURIComponent(r)}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!e.ok){let a=await e.json().catch(()=>({}));throw new Error(a.message||`Failed to fetch deposit history: ${e.status} ${e.statusText}`)}let i=await e.json();if(typeof i!="object"||i===null)throw new Error("Invalid response format from server");if(typeof i.userAddress!="string")throw new Error("Invalid userAddress in response");return i}catch(e){throw e instanceof Error?e:new Error("Unknown error occurred while fetching deposit history")}}import{PublicKey as S,Transaction as O,TransactionInstruction as R}from"@solana/web3.js";async function k({file:r,duration:s,payer:n,connection:e,signTransaction:i,userEmail:a}){try{let t=new FormData;r.forEach(o=>t.append("file",o)),t.append("duration",s.toString()),t.append("publicKey",n.toBase58()),a&&t.append("userEmail",a);let u=r.length>1,h,E=await fetch(`${l}/api/solana/deposit`,{method:"POST",body:t});if(!E.ok)throw new Error("Failed to get deposit instructions");let c=await E.json();if(!c.instructions||!c.instructions.length)throw new Error("No instructions from deposit API");let w=await e.getLatestBlockhash("confirmed"),g=c.instructions[0],v=new R({programId:new S(g.programId),keys:g.keys.map(o=>({pubkey:new S(o.pubkey),isSigner:o.isSigner,isWritable:o.isWritable})),data:Buffer.from(g.data,"base64")}),m=new O;m.recentBlockhash=w.blockhash,m.feePayer=n,m.add(v);let T=await i(m),y=await e.sendRawTransaction(T.serialize(),{skipPreflight:!1,preflightCommitment:"confirmed"}),D=await e.confirmTransaction({signature:y,blockhash:w.blockhash,lastValidBlockHeight:w.lastValidBlockHeight},"confirmed");if(D.value.err)throw console.error("Failed to confirm this transaction:",D.value.err),new Error(`Transaction failed: ${JSON.stringify(D.value.err)}`);try{await fetch(`${l}/api/user/update-transaction-hash`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cid:c.cid,transactionHash:y})})}catch(o){console.warn("Failed to update transaction hash:",o)}c.error&&(h=c.error);let b=new FormData;r.forEach(o=>b.append("file",o));let d;if(u?d=await fetch(`${l}/api/user/upload-files?cid=${encodeURIComponent(c.cid)}`,{method:"POST",body:b}):d=await fetch(`${l}/api/user/upload-file?cid=${encodeURIComponent(c.cid)}`,{method:"POST",body:b}),!d.ok){let o="Unknown error";try{let I=await d.json();o=I.message||I.error||o}catch{}throw new Error("Deposit API error: "+o)}let p=await d?.json();return{signature:y,success:!0,cid:c.cid,url:p.object.url,message:p.object.message,fileInfo:p.object?{filename:p.object.fileInfo?.filename||"",size:p?.object?.fileInfo?.size||0,uploadedAt:p?.object?.fileInfo?.uploadedAt||"",type:p?.object?.fileInfo?.type||""}:void 0}}catch(t){return console.error(t),t instanceof Error&&(console.error("Error name:",t.name),console.error("Error message:",t.message),console.error("Error stack:",t.stack)),{signature:"",success:!1,cid:"",url:"",message:"",fileInfo:void 0,error:t instanceof Error?t.message:"Unknown error occurred"}}}var j=(e=>(e.mainnet="mainnet-beta",e.testnet="testnet",e.devnet="devnet",e))(j||{});function N(r){switch(r){case"mainnet-beta":return"https://api.mainnet-beta.solana.com";case"testnet":return"https://api.testnet.solana.com";case"devnet":return"https://api.devnet.solana.com";default:throw new Error(`Unsupported environment: ${r}`)}}var f=class{constructor(s){this.estimateStorageCost=(s,n)=>{let a=s.reduce((u,h)=>u+h.size,0)*n*1e3;return{sol:a/1e9,lamports:a}};this.rpcUrl=N(s.environment)}async createDeposit({payer:s,file:n,durationDays:e,signTransaction:i,userEmail:a}){console.log("Creating deposit transaction with environment:",this.rpcUrl);let t=new C(this.rpcUrl,"confirmed");return await k({file:n,duration:e*P,payer:s,connection:t,signTransaction:i,userEmail:a})}async getUserUploadHistory(s){return await U(s)}};var Y=r=>new f({environment:r||"testnet"});export{f as Client,j as Environment,k as createDepositTxn,U as fetchUserDepositHistory,N as getRpcUrl,Y as useDeposit};
2
2
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "storacha-sol",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "main": "./dist/index.js",
5
5
  "scripts": {
6
6
  "build": "tsup src/index.ts --minify",
7
- "dev": "pnpm build --watch"
7
+ "dev": "pnpm build --watch",
8
+ "pack:local": "pnpm build && pnpm pack"
8
9
  },
9
10
  "exports": {
10
11
  "import": {