From 3b189b0e655a444968e6bb4ec5087f5c93336049 Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Wed, 15 May 2024 14:20:10 +0200 Subject: [PATCH 01/13] chore: symbolic link readme --- README.md | 29 +---------------------------- src/README.md | 33 +++++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 38 deletions(-) mode change 100644 => 120000 README.md diff --git a/README.md b/README.md deleted file mode 100644 index 7eddf7fb..00000000 --- a/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# ๐Ÿ”ฅ @effectai/effect-js - -

- -Effect-js is a free and open-source library powered by blockchain technology that enables developers to collect and enrich their data-sets in a transparent way. - -## ๐Ÿ—’๏ธ Documentation -For full documentation, visit https://docs.effect.ai - -## ๐Ÿ™‹ Contributing -If you want to add contributions to this repository, please follow the instructions in [contributing.md](CONTRIBUTING.md). - -## ๐Ÿ  Local Development -Follow the docs to Set Up Your Local Development Environment to contribute to the framework and documentation. - -### Testing - -#### `.env` - -To run the tests locally, you will need to provide an EOS account that can be used to make transactions on your behalf. -Copy the `.env.example` file to `.env.testnet` and fill in the required parameters. - -#### PowerUp - -You might need to power up your account, either by adding some Native Token to your account or EFX tokens. -You can powerup your account at the following link: https://monitor4.jungletestnet.io/ - - diff --git a/README.md b/README.md new file mode 120000 index 00000000..351df1da --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +src/README.md \ No newline at end of file diff --git a/src/README.md b/src/README.md index 9cea49a3..7eddf7fb 100644 --- a/src/README.md +++ b/src/README.md @@ -1,15 +1,28 @@ -# @effectai/sdk +# ๐Ÿ”ฅ @effectai/effect-js -To install dependencies: +

-```bash -bun install -``` +Effect-js is a free and open-source library powered by blockchain technology that enables developers to collect and enrich their data-sets in a transparent way. -To run: +## ๐Ÿ—’๏ธ Documentation +For full documentation, visit https://docs.effect.ai + +## ๐Ÿ™‹ Contributing +If you want to add contributions to this repository, please follow the instructions in [contributing.md](CONTRIBUTING.md). + +## ๐Ÿ  Local Development +Follow the docs to Set Up Your Local Development Environment to contribute to the framework and documentation. + +### Testing + +#### `.env` + +To run the tests locally, you will need to provide an EOS account that can be used to make transactions on your behalf. +Copy the `.env.example` file to `.env.testnet` and fill in the required parameters. + +#### PowerUp + +You might need to power up your account, either by adding some Native Token to your account or EFX tokens. +You can powerup your account at the following link: https://monitor4.jungletestnet.io/ -```bash -bun run dist/exports/index.js -``` -This project was created using `bun init` in bun v1.1.7. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. From cf5ce01598282508d8786a1833e6062e438bf397 Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Wed, 15 May 2024 15:10:02 +0200 Subject: [PATCH 02/13] docs: fix baseUrl --- docs/vocs.config.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/vocs.config.tsx b/docs/vocs.config.tsx index cf807b5d..39e851ec 100644 --- a/docs/vocs.config.tsx +++ b/docs/vocs.config.tsx @@ -3,8 +3,8 @@ import pkg from "../src/package.json"; import { sidebar } from "./sidebar"; export default defineConfig({ - baseUrl: "https://effect.ai", - title: "Effect JS", + baseUrl: "https://docs.effect.ai", + title: "Effect SDK Docs", titleTemplate: "%s ยท Effect.AI", description: "Effect-js is a free and open-source library powered by blockchain technology that enables developers to collect and enrich their data-sets in a transparent way.", From 61324f3bd204fb8e85b5c0aa52f59471b131c959 Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Wed, 15 May 2024 15:19:26 +0200 Subject: [PATCH 03/13] docs: fix package renamed references' --- docs/pages/docs/collecting-data/adding-tasks.mdx | 2 +- docs/pages/index.mdx | 6 +++--- docs/public/CNAME | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 docs/public/CNAME diff --git a/docs/pages/docs/collecting-data/adding-tasks.mdx b/docs/pages/docs/collecting-data/adding-tasks.mdx index 4c6e43a2..6808d168 100644 --- a/docs/pages/docs/collecting-data/adding-tasks.mdx +++ b/docs/pages/docs/collecting-data/adding-tasks.mdx @@ -4,7 +4,7 @@ Adding tasks to a campaign is done through batches batches are a collecti Let's start by creating a batch with 3 tasks to our newly created image classification campaign. ```ts [example.ts] -import { createBatch } from '@effectai/effect-js' +import { createBatch } from '@effectai/sdk' const { actor } = client.session diff --git a/docs/pages/index.mdx b/docs/pages/index.mdx index 68ba2a6d..b6b05049 100644 --- a/docs/pages/index.mdx +++ b/docs/pages/index.mdx @@ -36,15 +36,15 @@ style={{ :::code-group ```bash [npm] - npm i @effectai/effect-js + npm i @effectai/sdk ``` ```bash [pnpm] - pnpm i @effectai/effect-js + pnpm i @effectai/sdk ``` ```bash [bun] - bun i @effectai/effect-js + bun i @effectai/sdk ``` ::: diff --git a/docs/public/CNAME b/docs/public/CNAME new file mode 100644 index 00000000..ac776a72 --- /dev/null +++ b/docs/public/CNAME @@ -0,0 +1 @@ +docs.effect.ai \ No newline at end of file From e26a47f91300ef07af201564bf64f1bb8d224e78 Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Wed, 15 May 2024 15:20:35 +0200 Subject: [PATCH 04/13] chore: symbolic link readme --- LICENSE | 22 +--------------------- src/LICENSE | 21 +++++++++++++++++++++ src/README.md | 2 +- src/package.json | 13 +++++++++---- 4 files changed, 32 insertions(+), 26 deletions(-) mode change 100644 => 120000 LICENSE create mode 100644 src/LICENSE diff --git a/LICENSE b/LICENSE deleted file mode 100644 index a1594b3e..00000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Effect Network - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/LICENSE b/LICENSE new file mode 120000 index 00000000..da348fc8 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +src/LICENSE \ No newline at end of file diff --git a/src/LICENSE b/src/LICENSE new file mode 100644 index 00000000..a1594b3e --- /dev/null +++ b/src/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Effect Network + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/README.md b/src/README.md index 7eddf7fb..868aff8e 100644 --- a/src/README.md +++ b/src/README.md @@ -1,4 +1,4 @@ -# ๐Ÿ”ฅ @effectai/effect-js +# ๐Ÿ”ฅ @effectai/sdk

diff --git a/src/package.json b/src/package.json index 0fdbcf81..122e354b 100644 --- a/src/package.json +++ b/src/package.json @@ -6,14 +6,20 @@ "module": "./dist/exports/index.js", "browser": "dist/exports/index.js", "types": "./dist/exports/index.d.ts", - "files": ["dist"], + "files": [ + "dist" + ], "type": "module", - "repository": { "type": "git", "url": "git+https://github.com/effectai/effect-js.git" }, - "keywords": ["efx", "AI", "blockchain", "microtasks"], + "keywords": [ + "efx", + "AI", + "blockchain", + "microtasks" + ], "author": { "name": "Effect-AI", "url": "https://effect.network", @@ -27,7 +33,6 @@ "url": "https://github.com/effectai/effect-js/issues" }, "homepage": "https://github.com/effectai/effect-js#readme", - "devDependencies": { "@types/bun": "latest" }, From d656216bc1eb41d37b98d299171151139ff4cdac Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Wed, 15 May 2024 15:34:00 +0200 Subject: [PATCH 05/13] add changeset --- .changeset/new-chairs-provide.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/new-chairs-provide.md diff --git a/.changeset/new-chairs-provide.md b/.changeset/new-chairs-provide.md new file mode 100644 index 00000000..95ff5f33 --- /dev/null +++ b/.changeset/new-chairs-provide.md @@ -0,0 +1,5 @@ +--- +"@effectai/sdk": patch +--- + +add symlinks for license and README From 52e0533b1bf320d27cceb1e9f134096ff2425a9a Mon Sep 17 00:00:00 2001 From: Jeffrieh Date: Wed, 15 May 2024 13:37:46 +0000 Subject: [PATCH 06/13] chore: format --- src/package.json | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/package.json b/src/package.json index 122e354b..c65d9a36 100644 --- a/src/package.json +++ b/src/package.json @@ -6,20 +6,13 @@ "module": "./dist/exports/index.js", "browser": "dist/exports/index.js", "types": "./dist/exports/index.d.ts", - "files": [ - "dist" - ], + "files": ["dist"], "type": "module", "repository": { "type": "git", "url": "git+https://github.com/effectai/effect-js.git" }, - "keywords": [ - "efx", - "AI", - "blockchain", - "microtasks" - ], + "keywords": ["efx", "AI", "blockchain", "microtasks"], "author": { "name": "Effect-AI", "url": "https://effect.network", From 2b1bc112408db9e13e32765b8a2bc15999387051 Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Wed, 15 May 2024 15:52:24 +0200 Subject: [PATCH 07/13] chore: update readme --- src/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/README.md b/src/README.md index 868aff8e..7643ab8e 100644 --- a/src/README.md +++ b/src/README.md @@ -1,8 +1,8 @@ -# ๐Ÿ”ฅ @effectai/sdk +# ๐Ÿ”ฅ The @effectai/sdk Monorepo

-Effect-js is a free and open-source library powered by blockchain technology that enables developers to collect and enrich their data-sets in a transparent way. +The @effectai/sdk is a free and open source library for training next-gen transparent AI models. Integrate the SDK into your app and tap into a global, decentralized workforce powered by blockchain technology. ## ๐Ÿ—’๏ธ Documentation For full documentation, visit https://docs.effect.ai From 4dcb0094f40e10f4c6f16bfa7c44dccd43d6b71b Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Wed, 15 May 2024 16:06:32 +0200 Subject: [PATCH 08/13] chore: add link script --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 552f9201..b56eff1a 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,9 @@ "changeset:version": "changeset version && bun install --frozen-lockfile && bun scripts/updateVersion.ts", "docs:dev": "cd docs && bun run dev", "docs:build": "cd docs && bun run build", - "docs:preview": "cd docs && bun run preview" + "docs:preview": "cd docs && bun run preview", + "link": "cd src && bun link" + }, "devDependencies": { "@biomejs/biome": "1.7.0", From 56a7b7dec7bdd1b0b5ecd71ee682dd86039124f5 Mon Sep 17 00:00:00 2001 From: Jeffrieh Date: Wed, 15 May 2024 14:06:54 +0000 Subject: [PATCH 09/13] chore: format --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index b56eff1a..0b3244ca 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,6 @@ "docs:build": "cd docs && bun run build", "docs:preview": "cd docs && bun run preview", "link": "cd src && bun link" - }, "devDependencies": { "@biomejs/biome": "1.7.0", From 12ef26915e3029ae2018c6a80760fc94edda5c26 Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Wed, 15 May 2024 16:22:15 +0200 Subject: [PATCH 10/13] docs: update coverage --- docs/pages/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/index.mdx b/docs/pages/index.mdx index b6b05049..bdbbd247 100644 --- a/docs/pages/index.mdx +++ b/docs/pages/index.mdx @@ -69,7 +69,7 @@ style={{ coverage
- 0% + 63.34%
From e53a24c7e479f23c81c4e14859f6aa36f64533be Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Fri, 17 May 2024 17:29:17 +0200 Subject: [PATCH 11/13] fix: fix types for createBatch & add docs --- .changeset/new-chairs-provide.md | 3 +- bun.lockb | Bin 414892 -> 417884 bytes docs/package.json | 3 + docs/pages/docs/authentication.mdx | 62 ++++++++++++++++++ .../docs/collecting-data/adding-tasks.mdx | 44 ++++++++----- .../collecting-data/collecting-results.mdx | 3 + docs/public/.nojekyll | 0 docs/sidebar.ts | 5 ++ .../getting-started/getting-started-auth.ts | 7 +- src/actions/ipfs/uploadIpfsResource.ts | 2 +- src/actions/tasks/batch/createBatch.ts | 2 +- 11 files changed, 107 insertions(+), 24 deletions(-) create mode 100644 docs/pages/docs/authentication.mdx create mode 100644 docs/pages/docs/collecting-data/collecting-results.mdx create mode 100644 docs/public/.nojekyll diff --git a/.changeset/new-chairs-provide.md b/.changeset/new-chairs-provide.md index 95ff5f33..3cfe31f2 100644 --- a/.changeset/new-chairs-provide.md +++ b/.changeset/new-chairs-provide.md @@ -2,4 +2,5 @@ "@effectai/sdk": patch --- -add symlinks for license and README +- add symlinks for license and README +- fix createBatch types diff --git a/bun.lockb b/bun.lockb index 6d676796f4e407800a41942ad0f8b5ae40e8e181..69b420d55fd1f9e904d20c3854ef2c44d4342135 100755 GIT binary patch delta 35530 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 a+2ppCVFiv0{&aUs*3ueBNk!UO&ij9z1?*k` delta 33620 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 U6j%OMo?_$+kK$r~N6%^h2j%8h&Hw-a diff --git a/docs/package.json b/docs/package.json index b5f98582..4fe4bc40 100644 --- a/docs/package.json +++ b/docs/package.json @@ -9,6 +9,9 @@ }, "dependencies": {}, "devDependencies": { + "@wharfkit/wallet-plugin-anchor": "^1.0.0", + "@wharfkit/web-renderer": "^1.0.3", + "@wharfkit/wallet-plugin-privatekey": "1.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", "vocs": "^1.0.0-alpha.46", diff --git a/docs/pages/docs/authentication.mdx b/docs/pages/docs/authentication.mdx new file mode 100644 index 00000000..3d4cea5b --- /dev/null +++ b/docs/pages/docs/authentication.mdx @@ -0,0 +1,62 @@ +# Authentication +Some functions in the Effect AI SDK require authentication with the EOS blockchain. This is done by passing a session object to the createClient function. +A session can be established by either [private key](https://github.com/wharfkit/wallet-plugin-privatekey) or [wallet plugins](https://wharfkit.com/plugins?tag=wallet-plugin). + +### Private Key +To authenticate using a private key we recommend using the [wallet-plugin-privatekey](https://github.com/wharfkit/wallet-plugin-privatekey) +And passing it through a session to the `createClient` function. + +```ts twoslash +import { + createClient, + eos, + Session +} from "@effectai/sdk"; + +import { WalletPluginPrivateKey } from '@wharfkit/wallet-plugin-privatekey' + +const session = new Session({ + chain: eos, + walletPlugin: new WalletPluginPrivateKey( + '5Jtoxgny5tT7NiNFp1MLogviuPJ9NniWjnU4wKzaX4t7pL4kJ8s', + ), +}) + +const client = await createClient({ session }) +``` + +### Wallet Plugin +It's also possible to authenticate using a wallet plugin, for example using the [wallet-plugin-anchor](https://github.com/wharfkit/wallet-plugin-anchor) +This one is a bit more complicated and requires two additional packages: [`@wharfkit/session`](https://github.com/wharfkit/session) and [`@wharfkit/web-renderer`](https://github.com/wharfkit/web-renderer) + +```ts twoslash +import { + createClient, + eos, +} from "@effectai/sdk"; + +import { SessionKit } from "@wharfkit/session"; +import { WebRenderer } from "@wharfkit/web-renderer"; +import { WalletPluginAnchor } from "@wharfkit/wallet-plugin-anchor"; + +const webRenderer = new WebRenderer(); + +const sessionKit = new SessionKit( + { + appName: "Effect Network", + chains: [eos], + ui: webRenderer, + walletPlugins: [ + new WalletPluginAnchor(), + ], + }, + ) + +const session = await sessionKit.restore(); + +if(!session) { + throw new Error('Session not found') +} + +const client = await createClient({ session }) +``` \ No newline at end of file diff --git a/docs/pages/docs/collecting-data/adding-tasks.mdx b/docs/pages/docs/collecting-data/adding-tasks.mdx index 6808d168..998edd82 100644 --- a/docs/pages/docs/collecting-data/adding-tasks.mdx +++ b/docs/pages/docs/collecting-data/adding-tasks.mdx @@ -1,30 +1,44 @@ ## Adding tasks -Adding tasks to a campaign is done through batches batches are a collection of tasks that are added to a campaign. Each batch can contain multiple tasks. -Let's start by creating a batch with 3 tasks to our newly created image classification campaign. +Adding tasks to a campaign is done through adding batches. -```ts [example.ts] -import { createBatch } from '@effectai/sdk' +Batches are a collection of tasks that are added to a campaign. Each batch can contain multiple tasks. +Let's start by creating a batch with 3 tasks to our newly created image classification campaign. +```ts twoslash +// [!include ~/snippets/getting-started/getting-started-auth.ts] +if(!client.session) { + throw new Error('No session found') +} const { actor } = client.session +if(!actor) { + throw new Error('No actor found') +} +//---cut--- +import { createBatch } from '@effectai/sdk' + const batch = await createBatch({ client, - batch: { - campaign_id: '<..>', // the id of the campaign - repetitions: 1 // number of times each task should be repeated - payer: actor // the actor that will pay the workers for the tasks - } - data: [ + // The campaign id to which the batch should be added + campaignId : 1, + // The number of times each task in the batch should be repeated + repetitions: 1, + // The reward for each task in the batch + reward: 3, + // The template placeholders for each task in the batch + taskData : [ { - image: 'https://example.com/image.jpg', //task 1 image placeholder + ipfs_url: 'https://example.com/image.jpg', //task 1 image placeholder }, { - image: 'https://example.com/image2.jpg', //task 2 image placeholder + ipfs_url: 'https://example.com/image2.jpg', //task 2 image placeholder }, { - image: 'https://example.com/image3.jpg', // task 3 image placeholder + ipfs_url: 'https://example.com/image3.jpg', // task 3 image placeholder } - ] + ], }) -``` \ No newline at end of file + +``` + diff --git a/docs/pages/docs/collecting-data/collecting-results.mdx b/docs/pages/docs/collecting-data/collecting-results.mdx new file mode 100644 index 00000000..4b86553c --- /dev/null +++ b/docs/pages/docs/collecting-data/collecting-results.mdx @@ -0,0 +1,3 @@ +## Collecting Results + +TODO:: \ No newline at end of file diff --git a/docs/public/.nojekyll b/docs/public/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/docs/sidebar.ts b/docs/sidebar.ts index b810854f..f0bbbda5 100644 --- a/docs/sidebar.ts +++ b/docs/sidebar.ts @@ -7,6 +7,7 @@ export const sidebar = { items: [ { text: "Why Effect AI", link: "/docs/introduction" }, { text: "Getting Started", link: "/docs/getting-started" }, + { text: "Authentication", link: "/docs/authentication" }, ], }, { @@ -25,6 +26,10 @@ export const sidebar = { text: "Adding Tasks to a Campaign", link: "/docs/collecting-data/adding-tasks", }, + { + text: "Collecting results", + link: "/docs/collecting-data/collecting-results", + }, ], }, { diff --git a/docs/snippets/getting-started/getting-started-auth.ts b/docs/snippets/getting-started/getting-started-auth.ts index da0b77fa..56a7c727 100644 --- a/docs/snippets/getting-started/getting-started-auth.ts +++ b/docs/snippets/getting-started/getting-started-auth.ts @@ -16,9 +16,4 @@ const session = new Session({ }); // Create client to make authenticated transactions -const authClient = await createClient({ session }); - -// Create a new Effect Account -const account = "efxforce1112"; -const response = await createVAccount({ client: authClient, account }); -console.log(response); // => Transaction Details +const client = await createClient({ session }); diff --git a/src/actions/ipfs/uploadIpfsResource.ts b/src/actions/ipfs/uploadIpfsResource.ts index 3169aef9..6e4874f8 100644 --- a/src/actions/ipfs/uploadIpfsResource.ts +++ b/src/actions/ipfs/uploadIpfsResource.ts @@ -3,7 +3,7 @@ import { Bytes } from "@wharfkit/antelope"; export type UploadIpfsResourceArgs = { client: Client; - data: Record; + data: Record | Record[]; }; export const uploadIpfsResource = async ({ diff --git a/src/actions/tasks/batch/createBatch.ts b/src/actions/tasks/batch/createBatch.ts index 4de4b695..9862b622 100644 --- a/src/actions/tasks/batch/createBatch.ts +++ b/src/actions/tasks/batch/createBatch.ts @@ -84,7 +84,7 @@ export type CreateBatchArgs = { campaignId: number; repetitions: number; reward: number; - taskData: Record; + taskData: Record[]; }; export const createBatch = async ({ From bb176a2ce4ebf730aea84b23426180bb5f0b1767 Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Fri, 17 May 2024 17:45:42 +0200 Subject: [PATCH 12/13] docs: remove todo from docs --- docs/pages/docs/glossary/client-options.mdx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/pages/docs/glossary/client-options.mdx b/docs/pages/docs/glossary/client-options.mdx index d42ce0e8..b6752018 100644 --- a/docs/pages/docs/glossary/client-options.mdx +++ b/docs/pages/docs/glossary/client-options.mdx @@ -17,7 +17,7 @@ As we can see, the ClientOpts interface has three optional properties: This property is used to set the cache duration for the IPFS data. The default value is 600_000 milliseconds; 10 minutes. -## `fetchProfider` +## `fetchProvider` This property is used to set the fetch provider. This is needed because of the different runtimes availalbe to Java Script. @@ -45,6 +45,5 @@ const client = createClient({ }) ``` -# TODO: This needs to be changed when the `dev` branch is merged into main. [See Type](https://github.com/effectai/effect-js/blob/main/src/client.ts) From f61732a9f1a742d875d6e9b5e7a3e419bddd9e9f Mon Sep 17 00:00:00 2001 From: Jesse Eisses Date: Sat, 18 May 2024 00:55:43 +0200 Subject: [PATCH 13/13] Fix binary storage of submissions in `ipfsCIDToHex` it needs to be base58 encoded, not base64 --- src/actions/ipfs/uploadIpfsResource.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/actions/ipfs/uploadIpfsResource.ts b/src/actions/ipfs/uploadIpfsResource.ts index 3169aef9..109b11c9 100644 --- a/src/actions/ipfs/uploadIpfsResource.ts +++ b/src/actions/ipfs/uploadIpfsResource.ts @@ -1,5 +1,5 @@ import type { Client } from "../../client"; -import { Bytes } from "@wharfkit/antelope"; +import { Bytes, Base58 } from "@wharfkit/antelope"; export type UploadIpfsResourceArgs = { client: Client; @@ -46,10 +46,5 @@ export const uploadIpfsResource = async ({ }; export const ipfsCIDToHex = (cid: string): string => { - const string = atob(cid); - const array = new Uint8Array(string.length); - for (let i = 0; i < string.length; i++) { - array[i] = string.charCodeAt(i); - } - return Bytes.from(array).hexString; + return Base58.decode(cid).hexString; };