storacha-sol 0.0.1
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 +113 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +196 -0
- package/dist/index.d.ts +196 -0
- package/dist/index.js +2 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
## Storacha SOL
|
|
2
|
+
|
|
3
|
+
Crypto-native payments for storage on Storacha with SOL. No credit card needed.
|
|
4
|
+
|
|
5
|
+
Here are a couple of things you can do with this package:
|
|
6
|
+
|
|
7
|
+
- Estimate upload fees based on the file size and duration
|
|
8
|
+
- Make SOL payments for Storage on Storacha
|
|
9
|
+
|
|
10
|
+
Stuffs we hope to cover or extend:
|
|
11
|
+
|
|
12
|
+
- Multiple file (directory) uploads
|
|
13
|
+
- List stored items in a wallet's space (space-management, pretty-much)
|
|
14
|
+
- Allow payments from other chains. (Filecoin next)
|
|
15
|
+
- 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
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
First, install the package with your preferred package manager
|
|
21
|
+
|
|
22
|
+
```shell
|
|
23
|
+
pnpm add storacha-sol
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The package exposes a react hook `useDeposit` which you can access the `client` with. Because this runs on Solana for now, you'll need to install any of your preferred solana wallet-adapter libs tailored for React or JS in general
|
|
27
|
+
|
|
28
|
+
We recommend this one: [@solana/wallet-adpater-react](https://www.npmjs.com/package/@solana/wallet-adapter-react). It'll come in handy when you'll need it to sign the transaction from `client.createDeposit(args)`
|
|
29
|
+
|
|
30
|
+
In your component, import the `useDeposit` hook like so:
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import { useDeposit } from 'storacha-sol';
|
|
34
|
+
|
|
35
|
+
const UploadComponent = () => {
|
|
36
|
+
const client = useDeposit('testnet');
|
|
37
|
+
return <>// some markup</>;
|
|
38
|
+
};
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
From the snippet above, you'll see that the hook takes an environment argument `"testnet"`. If you leave it as is, Typescript would start crying. So, to appease it, you should import the `Environment` type from `storacha-sol` and infer it.
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { useDeposit, Environment } from "storacha-sol"
|
|
45
|
+
...
|
|
46
|
+
|
|
47
|
+
const client = useDeposit("testnet" as Environment)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
In your component, we'll assume you already have file and duration state variables
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import { useDeposit, Environment } from 'storacha-sol';
|
|
54
|
+
import { useSolanaWallet } from '@solana/wallet-adapter-react';
|
|
55
|
+
|
|
56
|
+
const UploadComponent = () => {
|
|
57
|
+
const [selectedFiles, setSelectedFiles] = useState<File>();
|
|
58
|
+
const [storageDuration, setStorageDuration] = useState(30);
|
|
59
|
+
const client = useDeposit('testnet' as Environment);
|
|
60
|
+
const { publicKey, signTransaction } = useSolanaWallet();
|
|
61
|
+
|
|
62
|
+
return <>// some markup</>;
|
|
63
|
+
};
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`createDeposit` expects the following args: `payer` (which is the publicKey, imported from wallet-adapter), `file`, `duration`, and the callback to sign a transaction.
|
|
67
|
+
|
|
68
|
+
See a sample of how you can achieve this below:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
const result = await client.createDeposit({
|
|
72
|
+
file,
|
|
73
|
+
durationDays: storageDuration,
|
|
74
|
+
payer: publicKey,
|
|
75
|
+
signTransaction: async (tx) => {
|
|
76
|
+
toast.loading('Please sign the transaction in your wallet...', {
|
|
77
|
+
id: 'upload-progress',
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
const signed = await signTransaction(tx);
|
|
82
|
+
toast.loading('Transaction sent to network...', {
|
|
83
|
+
id: 'upload-progress',
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return signed;
|
|
87
|
+
} catch (signError) {
|
|
88
|
+
console.error('❌ Transaction signing failed:', signError);
|
|
89
|
+
throw new Error(
|
|
90
|
+
`Transaction signing failed: ${signError instanceof Error ? signError.message : 'Unknown error'}`
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`storacha-sol` is type-safe, so you can always explore the content of the declaration file to see the structure. You could take a look at `UploadResult`, for starters.
|
|
98
|
+
|
|
99
|
+
and when `result` is successful, you can proceed with any other action you choose to carry out in your app.
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
if (result.success) {
|
|
103
|
+
// do more stuff
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
An edge-case you may want to consider before calling `createDeposit` is to check if the estimated storage cost is more than the wallet balance of the user, as this would fail to create the transaction.
|
|
108
|
+
|
|
109
|
+
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
|
+
|
|
111
|
+
## Want to contribute?
|
|
112
|
+
|
|
113
|
+
Read the [Contributing guide](CONTRIBUTING.md)
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var g=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var U=Object.prototype.hasOwnProperty;var C=(r,e)=>{for(var s in e)g(r,s,{get:e[s],enumerable:!0})},E=(r,e,s,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of S(e))!U.call(r,i)&&i!==s&&g(r,i,{get:()=>e[i],enumerable:!(o=I(e,i))||o.enumerable});return r};var B=r=>E(g({},"__esModule",{value:!0}),r);var T={};C(T,{Client:()=>l,Environment:()=>D,createDepositTxn:()=>h,getRpcUrl:()=>k,useDeposit:()=>R});module.exports=B(T);var b=require("@solana/web3.js");var c=require("@solana/web3.js");async function h({file:r,duration:e,payer:s,connection:o,signTransaction:i}){try{let t=new FormData;t.append("file",r),t.append("duration",e.toString()),t.append("publicKey",s.toBase58());let p=await fetch("http://localhost:5040/api/user/uploadFile",{method:"POST",body:t}),P;if(!p.ok){let a="Unknown error";try{let y=await p.json();a=y.message||y.error||a}catch{}throw new Error("Deposit API error: "+a)}let n=await p.json();if(!n.instructions||!n.instructions.length)throw new Error("No instructions from deposit API");let f=await o.getLatestBlockhash("confirmed"),u=n.instructions[0],x=new c.TransactionInstruction({programId:new c.PublicKey(u.programId),keys:u.keys.map(a=>({pubkey:new c.PublicKey(a.pubkey),isSigner:a.isSigner,isWritable:a.isWritable})),data:Buffer.from(u.data,"base64")});n.error&&(P=n.error);let m=new c.Transaction;m.recentBlockhash=f.blockhash,m.feePayer=s,m.add(x);let v=await i(m),w=await o.sendRawTransaction(v.serialize(),{skipPreflight:!1,preflightCommitment:"confirmed"}),d=await o.confirmTransaction({signature:w,blockhash:f.blockhash,lastValidBlockHeight:f.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)}`);return{signature:w,success:!0,cid:n.cid,url:n.object.url,message:n.message,fileInfo:n.object?{filename:n.object.fileInfo?.filename||"",size:n?.object?.fileInfo?.size||0,uploadedAt:n?.object?.fileInfo?.uploadedAt||"",type:n?.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 D=(o=>(o.mainnet="mainnet-beta",o.testnet="testnet",o.devnet="devnet",o))(D||{});function k(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,s)=>{let t=e.size*s*1e3;return{sol:t/1e9,lamports:t}};this.rpcUrl=k(e.environment)}async createDeposit({payer:e,file:s,durationDays:o,signTransaction:i}){console.log("Creating deposit transaction with environment:",this.rpcUrl);let t=new b.Connection(this.rpcUrl,"confirmed");return await h({file:s,duration:o*86400,payer:e,connection:t,signTransaction:i})}};var R=r=>new l({environment:r||"testnet"});0&&(module.exports={Client,Environment,createDepositTxn,getRpcUrl,useDeposit});
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/payment.ts","../src/hooks.ts"],"sourcesContent":["export * from \"./client\"\nexport * from \"./types\"\nexport * from \"./payment\"\nexport * from \"./hooks\"\n","import { PublicKey, Connection } from '@solana/web3.js';\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'> {\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","import { Signature } from '@solana/kit';\nimport { CreateDepositArgs, DepositResult, UploadResult } from './types';\nimport {\n PublicKey,\n Transaction,\n TransactionInstruction,\n} from '@solana/web3.js';\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 // calls the upload functionality on our server with the file to upload and\n // returns a response with the transaction instruction data\n const fileUploadReq = await fetch(\n 'http://localhost:5040/api/user/uploadFile',\n {\n method: 'POST',\n body: formData,\n }\n );\n let uploadErr;\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 body: DepositResult = await fileUploadReq.json();\n if (!body.instructions || !body.instructions.length) {\n throw new Error('No instructions from deposit API');\n }\n\n const latestBlockhash = await connection.getLatestBlockhash('confirmed');\n const instructions = body.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 if (body.error) {\n uploadErr = body.error;\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 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 return {\n signature: signature as Signature,\n success: true,\n cid: body.cid,\n url: body.object.url,\n message: body.message,\n fileInfo: body.object\n ? {\n filename: body.object.fileInfo?.filename || '',\n size: body?.object?.fileInfo?.size || 0,\n uploadedAt: body?.object?.fileInfo?.uploadedAt || '',\n type: body?.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","getRpcUrl","useDeposit","__toCommonJS","import_web3","import_web3","createDepositTxn","file","duration","payer","connection","signTransaction","formData","fileUploadReq","uploadErr","err","data","body","latestBlockhash","instructions","depositInstruction","k","tx","signedTx","signature","confirmation","error","Environment","getRpcUrl","env","Client","options","file","duration","totalLamports","payer","durationDays","signTransaction","connection","createDepositTxn","useDeposit","environment","Client"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { PublicKey, Connection, Transaction } from '@solana/web3.js';
|
|
2
|
+
import { Address, Signature } from '@solana/kit';
|
|
3
|
+
|
|
4
|
+
interface ServerOptions {
|
|
5
|
+
/** URL pointing to the backend (mostly Storacha's) */
|
|
6
|
+
url?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Options needed to create an on-chain deposit for storage
|
|
10
|
+
*/
|
|
11
|
+
interface UploadOptions {
|
|
12
|
+
/** content identifier for the data to be uploaded */
|
|
13
|
+
cid: string;
|
|
14
|
+
/** file/upload size in bytes */
|
|
15
|
+
size: number;
|
|
16
|
+
/** duration in days for how long the data should be retained */
|
|
17
|
+
duration: number;
|
|
18
|
+
/** wallet responsible for paying the deposit */
|
|
19
|
+
payer: Address;
|
|
20
|
+
/** optional Solana connection override (for testing or custom RPC) */
|
|
21
|
+
connection?: any;
|
|
22
|
+
/** Signature or transaction hash as proof of on-chain deposit */
|
|
23
|
+
signature?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Result returned after a successful file upload
|
|
27
|
+
*/
|
|
28
|
+
interface UploadResult {
|
|
29
|
+
/** message from the deposit transaction. could be an error or success message */
|
|
30
|
+
message?: string;
|
|
31
|
+
/** similar to message above but for error cases. can extrapoloate this later */
|
|
32
|
+
error?: string;
|
|
33
|
+
/** signature of the succesful transaction */
|
|
34
|
+
signature: Signature;
|
|
35
|
+
/** status of the request. successful or not. */
|
|
36
|
+
success: boolean;
|
|
37
|
+
/** CID of the uploaded content */
|
|
38
|
+
cid: string;
|
|
39
|
+
/** full URL where the content was uploaded to (on IPFS) */
|
|
40
|
+
url: string;
|
|
41
|
+
/** information of the file that was uploaded */
|
|
42
|
+
fileInfo?: {
|
|
43
|
+
/** file type */
|
|
44
|
+
type: string;
|
|
45
|
+
/** size of the uploaded content (in bytes) */
|
|
46
|
+
size: number;
|
|
47
|
+
/** UNIX timestamp (in seconds) of the time the file was uploaded */
|
|
48
|
+
uploadedAt: string;
|
|
49
|
+
/** name of the file uploaded */
|
|
50
|
+
filename: string;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Stored item entry returned when listing wallet space
|
|
55
|
+
*/
|
|
56
|
+
interface WalletItem {
|
|
57
|
+
/** CID of the stored item */
|
|
58
|
+
cid: string;
|
|
59
|
+
/** file size in bytes */
|
|
60
|
+
size: number;
|
|
61
|
+
/** expiration timestamp in seconds */
|
|
62
|
+
expiresAt: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Config values fetched from the on-chain ConfigAccount
|
|
66
|
+
*/
|
|
67
|
+
interface OnChainConfig {
|
|
68
|
+
/** current rate in lamports per byte per day */
|
|
69
|
+
ratePerBytePerDay: bigint;
|
|
70
|
+
/** minimum required duration in days */
|
|
71
|
+
minDurationDays: number;
|
|
72
|
+
/** wallet where provider can withdraw claimed funds */
|
|
73
|
+
withdrawalWallet: Address;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Deposit details stored on-chain for each user upload
|
|
77
|
+
*/
|
|
78
|
+
interface OnChainDeposit {
|
|
79
|
+
/** public key of the depositor */
|
|
80
|
+
depositor: Address;
|
|
81
|
+
/** file object containing metadata about the upload */
|
|
82
|
+
file: File;
|
|
83
|
+
/** storage duration (days) */
|
|
84
|
+
duration: number;
|
|
85
|
+
/** amount deposited in lamports */
|
|
86
|
+
depositAmount: bigint;
|
|
87
|
+
/** slot when deposit was made */
|
|
88
|
+
depositSlot: number;
|
|
89
|
+
/** last claimed slot for reward release */
|
|
90
|
+
lastClaimedSlot: number;
|
|
91
|
+
}
|
|
92
|
+
interface DepositResult extends Pick<UploadResult, 'message' | 'error'> {
|
|
93
|
+
/** CID of the stored item */
|
|
94
|
+
cid: string;
|
|
95
|
+
/** transaction instruction */
|
|
96
|
+
instructions: Array<{
|
|
97
|
+
programId: string;
|
|
98
|
+
keys: Array<{
|
|
99
|
+
pubkey: string;
|
|
100
|
+
isSigner: boolean;
|
|
101
|
+
isWritable: boolean;
|
|
102
|
+
}>;
|
|
103
|
+
data: string;
|
|
104
|
+
}>;
|
|
105
|
+
/** result of a successful upload */
|
|
106
|
+
object: UploadResult;
|
|
107
|
+
}
|
|
108
|
+
interface CreateDepositArgs extends Omit<OnChainDeposit, 'depositAmount' | 'depositor' | 'depositSlot' | 'lastClaimedSlot'> {
|
|
109
|
+
/** Public key of the user paying for the upload */
|
|
110
|
+
payer: PublicKey;
|
|
111
|
+
/** Wallet connection used to query chain state or recent blockhash */
|
|
112
|
+
connection: Connection;
|
|
113
|
+
/**
|
|
114
|
+
* a callback function to authorize the transaction via the solana wallet lib
|
|
115
|
+
* @example
|
|
116
|
+
* const {publickKey, signTransaction} = useSolanaWallet()
|
|
117
|
+
* const signTransaction = await signTransaction(tx)
|
|
118
|
+
* */
|
|
119
|
+
signTransaction: (tx: Transaction) => Promise<Transaction>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
declare enum Environment {
|
|
123
|
+
mainnet = "mainnet-beta",
|
|
124
|
+
testnet = "testnet",
|
|
125
|
+
devnet = "devnet"
|
|
126
|
+
}
|
|
127
|
+
declare function getRpcUrl(env: Environment): string;
|
|
128
|
+
interface ClientOptions {
|
|
129
|
+
/** Solana RPC endpoint to use for chain interactions */
|
|
130
|
+
environment: Environment;
|
|
131
|
+
}
|
|
132
|
+
interface DepositParams extends Pick<CreateDepositArgs, 'signTransaction'> {
|
|
133
|
+
/** Wallet public key of the payer */
|
|
134
|
+
payer: PublicKey;
|
|
135
|
+
/** File to be stored */
|
|
136
|
+
file: File;
|
|
137
|
+
/** Duration in days to store the data */
|
|
138
|
+
durationDays: number;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Solana Storage Client — simplified (no fee estimation)
|
|
142
|
+
*/
|
|
143
|
+
declare class Client {
|
|
144
|
+
private rpcUrl;
|
|
145
|
+
constructor(options: ClientOptions);
|
|
146
|
+
/**
|
|
147
|
+
* Creates a deposit transaction ready to be signed & sent by user's wallet.
|
|
148
|
+
*
|
|
149
|
+
* @param {Object} params
|
|
150
|
+
* @param {PublicKey} params.payer - The public key (wallet address) of the connected wallet.
|
|
151
|
+
* @param {File} params.file - The file to be uploaded.
|
|
152
|
+
* @param {number} params.durationDays - How long (in days) the file should be stored.
|
|
153
|
+
* @param {(tx: Transaction) => Promise<Transaction>} params.signTransaction -
|
|
154
|
+
* A callback function to authorize the transaction via the Solana wallet library.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* const { publicKey, signTransaction } = useSolanaWallet();
|
|
158
|
+
* const result = await createDeposit({
|
|
159
|
+
* payer: publicKey,
|
|
160
|
+
* file,
|
|
161
|
+
* durationDays: 30,
|
|
162
|
+
* signTransaction,
|
|
163
|
+
* });
|
|
164
|
+
*
|
|
165
|
+
* @returns {Promise<UploadResult>} The upload result after transaction is processed.
|
|
166
|
+
*/
|
|
167
|
+
createDeposit({ payer, file, durationDays, signTransaction, }: DepositParams): Promise<UploadResult>;
|
|
168
|
+
/**
|
|
169
|
+
* estimates the cost for a file based on the amount of days it should be stored for
|
|
170
|
+
* @param {File} file - a file to be uploaded
|
|
171
|
+
* @param {number} duration - how long (in seconds) the file should be stored for
|
|
172
|
+
*/
|
|
173
|
+
estimateStorageCost: (file: File, duration: number) => {
|
|
174
|
+
sol: number;
|
|
175
|
+
lamports: number;
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Calls the deposit API for on-chain storage and returns a Transaction
|
|
181
|
+
* which must be signed and sent externally by the user.
|
|
182
|
+
*
|
|
183
|
+
* @param params - {
|
|
184
|
+
* cid: string;
|
|
185
|
+
* file: File;
|
|
186
|
+
* duration: number;
|
|
187
|
+
* payer: PublicKey;
|
|
188
|
+
* connection: Connection;
|
|
189
|
+
* }
|
|
190
|
+
* @returns Transaction
|
|
191
|
+
*/
|
|
192
|
+
declare function createDepositTxn({ file, duration, payer, connection, signTransaction, }: CreateDepositArgs): Promise<UploadResult>;
|
|
193
|
+
|
|
194
|
+
declare const useDeposit: (environment: ClientOptions["environment"]) => Client;
|
|
195
|
+
|
|
196
|
+
export { Client, type ClientOptions, type CreateDepositArgs, type DepositParams, type DepositResult, Environment, type OnChainConfig, type OnChainDeposit, type ServerOptions, type UploadOptions, type UploadResult, type WalletItem, createDepositTxn, getRpcUrl, useDeposit };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { PublicKey, Connection, Transaction } from '@solana/web3.js';
|
|
2
|
+
import { Address, Signature } from '@solana/kit';
|
|
3
|
+
|
|
4
|
+
interface ServerOptions {
|
|
5
|
+
/** URL pointing to the backend (mostly Storacha's) */
|
|
6
|
+
url?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Options needed to create an on-chain deposit for storage
|
|
10
|
+
*/
|
|
11
|
+
interface UploadOptions {
|
|
12
|
+
/** content identifier for the data to be uploaded */
|
|
13
|
+
cid: string;
|
|
14
|
+
/** file/upload size in bytes */
|
|
15
|
+
size: number;
|
|
16
|
+
/** duration in days for how long the data should be retained */
|
|
17
|
+
duration: number;
|
|
18
|
+
/** wallet responsible for paying the deposit */
|
|
19
|
+
payer: Address;
|
|
20
|
+
/** optional Solana connection override (for testing or custom RPC) */
|
|
21
|
+
connection?: any;
|
|
22
|
+
/** Signature or transaction hash as proof of on-chain deposit */
|
|
23
|
+
signature?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Result returned after a successful file upload
|
|
27
|
+
*/
|
|
28
|
+
interface UploadResult {
|
|
29
|
+
/** message from the deposit transaction. could be an error or success message */
|
|
30
|
+
message?: string;
|
|
31
|
+
/** similar to message above but for error cases. can extrapoloate this later */
|
|
32
|
+
error?: string;
|
|
33
|
+
/** signature of the succesful transaction */
|
|
34
|
+
signature: Signature;
|
|
35
|
+
/** status of the request. successful or not. */
|
|
36
|
+
success: boolean;
|
|
37
|
+
/** CID of the uploaded content */
|
|
38
|
+
cid: string;
|
|
39
|
+
/** full URL where the content was uploaded to (on IPFS) */
|
|
40
|
+
url: string;
|
|
41
|
+
/** information of the file that was uploaded */
|
|
42
|
+
fileInfo?: {
|
|
43
|
+
/** file type */
|
|
44
|
+
type: string;
|
|
45
|
+
/** size of the uploaded content (in bytes) */
|
|
46
|
+
size: number;
|
|
47
|
+
/** UNIX timestamp (in seconds) of the time the file was uploaded */
|
|
48
|
+
uploadedAt: string;
|
|
49
|
+
/** name of the file uploaded */
|
|
50
|
+
filename: string;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Stored item entry returned when listing wallet space
|
|
55
|
+
*/
|
|
56
|
+
interface WalletItem {
|
|
57
|
+
/** CID of the stored item */
|
|
58
|
+
cid: string;
|
|
59
|
+
/** file size in bytes */
|
|
60
|
+
size: number;
|
|
61
|
+
/** expiration timestamp in seconds */
|
|
62
|
+
expiresAt: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Config values fetched from the on-chain ConfigAccount
|
|
66
|
+
*/
|
|
67
|
+
interface OnChainConfig {
|
|
68
|
+
/** current rate in lamports per byte per day */
|
|
69
|
+
ratePerBytePerDay: bigint;
|
|
70
|
+
/** minimum required duration in days */
|
|
71
|
+
minDurationDays: number;
|
|
72
|
+
/** wallet where provider can withdraw claimed funds */
|
|
73
|
+
withdrawalWallet: Address;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Deposit details stored on-chain for each user upload
|
|
77
|
+
*/
|
|
78
|
+
interface OnChainDeposit {
|
|
79
|
+
/** public key of the depositor */
|
|
80
|
+
depositor: Address;
|
|
81
|
+
/** file object containing metadata about the upload */
|
|
82
|
+
file: File;
|
|
83
|
+
/** storage duration (days) */
|
|
84
|
+
duration: number;
|
|
85
|
+
/** amount deposited in lamports */
|
|
86
|
+
depositAmount: bigint;
|
|
87
|
+
/** slot when deposit was made */
|
|
88
|
+
depositSlot: number;
|
|
89
|
+
/** last claimed slot for reward release */
|
|
90
|
+
lastClaimedSlot: number;
|
|
91
|
+
}
|
|
92
|
+
interface DepositResult extends Pick<UploadResult, 'message' | 'error'> {
|
|
93
|
+
/** CID of the stored item */
|
|
94
|
+
cid: string;
|
|
95
|
+
/** transaction instruction */
|
|
96
|
+
instructions: Array<{
|
|
97
|
+
programId: string;
|
|
98
|
+
keys: Array<{
|
|
99
|
+
pubkey: string;
|
|
100
|
+
isSigner: boolean;
|
|
101
|
+
isWritable: boolean;
|
|
102
|
+
}>;
|
|
103
|
+
data: string;
|
|
104
|
+
}>;
|
|
105
|
+
/** result of a successful upload */
|
|
106
|
+
object: UploadResult;
|
|
107
|
+
}
|
|
108
|
+
interface CreateDepositArgs extends Omit<OnChainDeposit, 'depositAmount' | 'depositor' | 'depositSlot' | 'lastClaimedSlot'> {
|
|
109
|
+
/** Public key of the user paying for the upload */
|
|
110
|
+
payer: PublicKey;
|
|
111
|
+
/** Wallet connection used to query chain state or recent blockhash */
|
|
112
|
+
connection: Connection;
|
|
113
|
+
/**
|
|
114
|
+
* a callback function to authorize the transaction via the solana wallet lib
|
|
115
|
+
* @example
|
|
116
|
+
* const {publickKey, signTransaction} = useSolanaWallet()
|
|
117
|
+
* const signTransaction = await signTransaction(tx)
|
|
118
|
+
* */
|
|
119
|
+
signTransaction: (tx: Transaction) => Promise<Transaction>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
declare enum Environment {
|
|
123
|
+
mainnet = "mainnet-beta",
|
|
124
|
+
testnet = "testnet",
|
|
125
|
+
devnet = "devnet"
|
|
126
|
+
}
|
|
127
|
+
declare function getRpcUrl(env: Environment): string;
|
|
128
|
+
interface ClientOptions {
|
|
129
|
+
/** Solana RPC endpoint to use for chain interactions */
|
|
130
|
+
environment: Environment;
|
|
131
|
+
}
|
|
132
|
+
interface DepositParams extends Pick<CreateDepositArgs, 'signTransaction'> {
|
|
133
|
+
/** Wallet public key of the payer */
|
|
134
|
+
payer: PublicKey;
|
|
135
|
+
/** File to be stored */
|
|
136
|
+
file: File;
|
|
137
|
+
/** Duration in days to store the data */
|
|
138
|
+
durationDays: number;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Solana Storage Client — simplified (no fee estimation)
|
|
142
|
+
*/
|
|
143
|
+
declare class Client {
|
|
144
|
+
private rpcUrl;
|
|
145
|
+
constructor(options: ClientOptions);
|
|
146
|
+
/**
|
|
147
|
+
* Creates a deposit transaction ready to be signed & sent by user's wallet.
|
|
148
|
+
*
|
|
149
|
+
* @param {Object} params
|
|
150
|
+
* @param {PublicKey} params.payer - The public key (wallet address) of the connected wallet.
|
|
151
|
+
* @param {File} params.file - The file to be uploaded.
|
|
152
|
+
* @param {number} params.durationDays - How long (in days) the file should be stored.
|
|
153
|
+
* @param {(tx: Transaction) => Promise<Transaction>} params.signTransaction -
|
|
154
|
+
* A callback function to authorize the transaction via the Solana wallet library.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* const { publicKey, signTransaction } = useSolanaWallet();
|
|
158
|
+
* const result = await createDeposit({
|
|
159
|
+
* payer: publicKey,
|
|
160
|
+
* file,
|
|
161
|
+
* durationDays: 30,
|
|
162
|
+
* signTransaction,
|
|
163
|
+
* });
|
|
164
|
+
*
|
|
165
|
+
* @returns {Promise<UploadResult>} The upload result after transaction is processed.
|
|
166
|
+
*/
|
|
167
|
+
createDeposit({ payer, file, durationDays, signTransaction, }: DepositParams): Promise<UploadResult>;
|
|
168
|
+
/**
|
|
169
|
+
* estimates the cost for a file based on the amount of days it should be stored for
|
|
170
|
+
* @param {File} file - a file to be uploaded
|
|
171
|
+
* @param {number} duration - how long (in seconds) the file should be stored for
|
|
172
|
+
*/
|
|
173
|
+
estimateStorageCost: (file: File, duration: number) => {
|
|
174
|
+
sol: number;
|
|
175
|
+
lamports: number;
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Calls the deposit API for on-chain storage and returns a Transaction
|
|
181
|
+
* which must be signed and sent externally by the user.
|
|
182
|
+
*
|
|
183
|
+
* @param params - {
|
|
184
|
+
* cid: string;
|
|
185
|
+
* file: File;
|
|
186
|
+
* duration: number;
|
|
187
|
+
* payer: PublicKey;
|
|
188
|
+
* connection: Connection;
|
|
189
|
+
* }
|
|
190
|
+
* @returns Transaction
|
|
191
|
+
*/
|
|
192
|
+
declare function createDepositTxn({ file, duration, payer, connection, signTransaction, }: CreateDepositArgs): Promise<UploadResult>;
|
|
193
|
+
|
|
194
|
+
declare const useDeposit: (environment: ClientOptions["environment"]) => Client;
|
|
195
|
+
|
|
196
|
+
export { Client, type ClientOptions, type CreateDepositArgs, type DepositParams, type DepositResult, Environment, type OnChainConfig, type OnChainDeposit, type ServerOptions, type UploadOptions, type UploadResult, type WalletItem, createDepositTxn, getRpcUrl, useDeposit };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{Connection as x}from"@solana/web3.js";import{PublicKey as h,Transaction as k,TransactionInstruction as P}from"@solana/web3.js";async function w({file:n,duration:o,payer:i,connection:r,signTransaction:a}){try{let e=new FormData;e.append("file",n),e.append("duration",o.toString()),e.append("publicKey",i.toBase58());let c=await fetch("http://localhost:5040/api/user/uploadFile",{method:"POST",body:e}),y;if(!c.ok){let s="Unknown error";try{let g=await c.json();s=g.message||g.error||s}catch{}throw new Error("Deposit API error: "+s)}let t=await c.json();if(!t.instructions||!t.instructions.length)throw new Error("No instructions from deposit API");let m=await r.getLatestBlockhash("confirmed"),f=t.instructions[0],b=new P({programId:new h(f.programId),keys:f.keys.map(s=>({pubkey:new h(s.pubkey),isSigner:s.isSigner,isWritable:s.isWritable})),data:Buffer.from(f.data,"base64")});t.error&&(y=t.error);let l=new k;l.recentBlockhash=m.blockhash,l.feePayer=i,l.add(b);let D=await a(l),d=await r.sendRawTransaction(D.serialize(),{skipPreflight:!1,preflightCommitment:"confirmed"}),u=await r.confirmTransaction({signature:d,blockhash:m.blockhash,lastValidBlockHeight:m.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)}`);return{signature:d,success:!0,cid:t.cid,url:t.object.url,message:t.message,fileInfo:t.object?{filename:t.object.fileInfo?.filename||"",size:t?.object?.fileInfo?.size||0,uploadedAt:t?.object?.fileInfo?.uploadedAt||"",type:t?.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"}}}var v=(r=>(r.mainnet="mainnet-beta",r.testnet="testnet",r.devnet="devnet",r))(v||{});function I(n){switch(n){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: ${n}`)}}var p=class{constructor(o){this.estimateStorageCost=(o,i)=>{let e=o.size*i*1e3;return{sol:e/1e9,lamports:e}};this.rpcUrl=I(o.environment)}async createDeposit({payer:o,file:i,durationDays:r,signTransaction:a}){console.log("Creating deposit transaction with environment:",this.rpcUrl);let e=new x(this.rpcUrl,"confirmed");return await w({file:i,duration:r*86400,payer:o,connection:e,signTransaction:a})}};var A=n=>new p({environment:n||"testnet"});export{p as Client,v as Environment,w as createDepositTxn,I as getRpcUrl,A as useDeposit};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "storacha-sol",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"main": "./dist/index.js",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "tsup src/index.ts --minify",
|
|
7
|
+
"dev": "pnpm build --watch"
|
|
8
|
+
},
|
|
9
|
+
"exports": {
|
|
10
|
+
"import": {
|
|
11
|
+
"node": "./dist/index.cjs",
|
|
12
|
+
"browser": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": "./dist/index.cjs"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"!dist/**/*.js.map"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/seetadev/storacha-solana-sdk"
|
|
24
|
+
},
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"type": "module",
|
|
27
|
+
"module": "./dist/index.js",
|
|
28
|
+
"keywords": ["solana", "storacha", "typescript", "rust", "dapp"],
|
|
29
|
+
"author": "",
|
|
30
|
+
"license": "ISC",
|
|
31
|
+
"description": "",
|
|
32
|
+
"packageManager": "pnpm@10.11.0",
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@solana/kit": "^2.3.0",
|
|
35
|
+
"@solana/web3.js": "^1.98.2"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"esbuild": "^0.21.4",
|
|
39
|
+
"tsup": "^8.5.0",
|
|
40
|
+
"typescript": "^5.8.3"
|
|
41
|
+
}
|
|
42
|
+
}
|