-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: implement unit and e2e tests for main methods docs: add documentation build: update ci pipeline docs: update README.md
- Loading branch information
1 parent
7e2e6e4
commit 55471f7
Showing
21 changed files
with
2,667 additions
and
159 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
P_KEY= |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
name: Web3.js Ipfs Plugin Pipeline | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
build-and-test: | ||
runs-on: ubuntu-latest | ||
env: | ||
P_KEY: ${{ secrets.P_KEY }} | ||
|
||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v2 | ||
|
||
- name: Install dependencies | ||
run: yarn install | ||
|
||
- name: Run unit tests | ||
run: yarn test | ||
|
||
- name: Run e2e tests | ||
run: yarn test:e2e |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
node_modules | ||
lib | ||
lib | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,65 @@ | ||
web3-plugin-template | ||
=========== | ||
# Web3.js IPFS Plugin | ||
|
||
This is a template for creating a repository for web3.js plugin. | ||
This is a plugin for Web3.js library, designed for uploading files to IPFS, storing CIDs in a smart contract, and listing all stored CIDs of given ethereum address. | ||
|
||
How to use | ||
------------ | ||
## Using the library | ||
|
||
1. Create your project out of this template. | ||
1. Instantiate a Web3 instance and register the plugin | ||
|
||
You can do so by pressing on `Use this template` on the above right corner and then select `Create new Repositor`. Please, use the convention `web3-plugin-<name>` for your repo name. | ||
2. Update the `name` and `description` fileds at your `package.json`. | ||
``` | ||
import { Web3 } from "web3"; | ||
import { IpfsPlugin } from "web3-ipfs-plugin"; | ||
Chose a name like: `@<organization>/web3-plugin-<name>` (or the less better `web3-plugin-<name>`). | ||
3. Update the code inside `src` folder. | ||
web3 = new Web3("RPC_URL"); | ||
web3.registerPlugin(new IpfsPlugin("RPC_URL")); | ||
``` | ||
|
||
4. Modify and add tests inside `test` folder. | ||
2. Use uploadFile() to upload a file to IPFS network and store the generated CID in a Registry Smart Contract `0xA683BF985BC560c5dc99e8F33f3340d1e53736EB` | ||
|
||
5. Publish to the npm registry. | ||
``` | ||
// Calling this method will upload the file to IPFS, store the CID to a smart contract, and return the transaction receipt (or throws an error if something goes wrong) | ||
try { | ||
const receipt = await web3.ipfs.uploadFile("path/to/file/"); | ||
} catch (e) { | ||
// handle error | ||
} | ||
``` | ||
|
||
You can publish with something like: `yarn build && npm publish --access public`. | ||
NOTE: If calling from a web browser, the file data should be passed as an Iterable<Uint8Array>, as the 2nd argument (since file path implementation uses `fs` underneath the hood which is only supported on a node environment) | ||
We suggest using [File System API](https://developer.mozilla.org/en-US/docs/Web/API/File_System_API) to implement client-side code capable of fetching and manipulating this data accordingly | ||
|
||
Contributing | ||
------------ | ||
``` | ||
try { | ||
const receipt = await web3.ipfs.uploadFile( | ||
"this/path/becomes/irrelevant", | ||
data | ||
); | ||
} catch (e) { | ||
// handle error | ||
} | ||
``` | ||
|
||
Pull requests are welcome. For major changes, please open an issue first | ||
to discuss what you would like to change. | ||
3. Use listAllByAddress() to list all encoded CIDs for given Ethereum address (or throws an error if something goes wrong) | ||
|
||
Please make sure to update tests as appropriate. | ||
``` | ||
try { | ||
const cidStoredEvents = await web3.ipfs.listAllByAddress("0xb9089c00f17B7c9Cf77f3Fb87164CbD0eC1F7d08"); | ||
} catch(e) { | ||
// handle error... | ||
} | ||
``` | ||
|
||
License | ||
------- | ||
NOTE: A limitation on Web3.js lib makes it so only data from the most recent 50000 blocks can be retrieved | ||
|
||
[MIT](https://choosealicense.com/licenses/mit/) | ||
## Running Tests | ||
|
||
1. To run unit tests, run the following command | ||
`yarn test` | ||
|
||
2. To run end to end tests, run the following command | ||
`yarn test:e2e` | ||
|
||
NOTE: `/!\` Make sure to add a private key (without the `0x` prefix) to the `P_KEY` environment variable | ||
as specified from the `.env.sample` file, before running e2e tests. | ||
If e2e test fails due to insufficient funds in the address you chose to use, just mint some SepoliaETH | ||
You can use this [faucet](https://sepolia-faucet.pk910.de/#/) `/!\` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/** @type {import('ts-jest').JestConfigWithTsJest} */ | ||
const IS_E2E = process.env.IS_E2E === "true"; | ||
|
||
let testRegex = ".*\\.spec\\.ts$"; | ||
if (IS_E2E) { | ||
testRegex = ".e2e-spec.ts$"; | ||
} | ||
const testPathIgnorePatterns = ["/lib/"]; | ||
module.exports = { | ||
preset: "ts-jest", | ||
moduleFileExtensions: ["js", "json", "ts"], | ||
moduleDirectories: ["node_modules", "src"], | ||
moduleNameMapper: { | ||
"^@helia/unixfs$": "<rootDir>/node_modules/@helia/unixfs/dist/src/index.js", | ||
}, | ||
testEnvironment: "node", | ||
testPathIgnorePatterns, | ||
testRegex, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { createReadStream } from "fs"; | ||
import { UnixFS } from "@helia/unixfs"; | ||
/** | ||
* An abstraction for encapsulating helia IPFS operations. | ||
*/ | ||
export class IpfsClient { | ||
private unixFsInstance?: UnixFS; | ||
|
||
/** | ||
* Uploads local files to IPFS. | ||
* `NOTE: /!\ if calling from web browser, use File System Access API to fetch data, and pass it in 2nd optional param, as implementation via filePath uses "fs" which is only supported in a Node environment. /!\` | ||
* @param {string} filePath local path of the file to upload. | ||
* @param {Iterable<Uint8Array>} data file as byte array. `/!\ use this optional param when calling this method from a web browser /!\` | ||
* @returns {string} generated CID from uploaded file. If an error is thrown, returns an empty string. | ||
*/ | ||
public async uploadFile( | ||
filePath: string, | ||
data?: Iterable<Uint8Array> | ||
): Promise<string> { | ||
try { | ||
if (!this.unixFsInstance) { | ||
await this.initUnixFSInstance(); | ||
} | ||
|
||
const cid = await this.unixFsInstance?.addByteStream( | ||
data ?? createReadStream(filePath) | ||
); | ||
return cid?.toString() ?? ""; | ||
} catch (e) { | ||
const err = e as Error; | ||
const msg = `error while uploading file: ${err.message}`; | ||
console.error(msg, err.stack); | ||
throw new Error(msg); | ||
} | ||
} | ||
|
||
/** | ||
* Spawns a UnixFS instance to be used for uploading files to IPFS. Since this is asynchronous behavior, we cannot do it in the class constructor. | ||
*/ | ||
private async initUnixFSInstance(): Promise<void> { | ||
try { | ||
/** | ||
* we do dynamic import in order for e2e tests to run properly, because of an issue with how the library is exposed. | ||
* issue: https://github.com/ipfs/helia/issues/149 | ||
*/ | ||
const [ | ||
{ createHelia }, | ||
{ createLibp2p }, | ||
{ tcp }, | ||
{ noise }, | ||
{ yamux }, | ||
{ MemoryBlockstore }, | ||
{ MemoryDatastore }, | ||
{ unixfs }, | ||
] = await Promise.all([ | ||
import("helia"), | ||
import("libp2p"), | ||
import("@libp2p/tcp"), | ||
import("@chainsafe/libp2p-noise"), | ||
import("@chainsafe/libp2p-yamux"), | ||
import("blockstore-core"), | ||
import("datastore-core"), | ||
import("@helia/unixfs"), | ||
]); | ||
|
||
const datastore = new MemoryDatastore(); | ||
const libp2p = await createLibp2p({ | ||
addresses: { | ||
listen: ["/ip4/0.0.0.0/tcp/0"], | ||
}, | ||
transports: [tcp()], | ||
connectionEncryption: [noise()], | ||
streamMuxers: [yamux()], | ||
datastore, | ||
}); | ||
|
||
const helia = await createHelia({ | ||
libp2p, | ||
blockstore: new MemoryBlockstore(), | ||
datastore, | ||
}); | ||
|
||
this.unixFsInstance = unixfs(helia); | ||
} catch (e) { | ||
console.error("error while initiating ipfs client: ", e); | ||
} | ||
} | ||
} |
Oops, something went wrong.