diff --git a/biome.json b/biome.json index be2e07dd..d986a83d 100644 --- a/biome.json +++ b/biome.json @@ -5,10 +5,10 @@ }, "formatter": { "enabled": true, - "ignore": ["dist", "test", "docs"] + "ignore": ["dist", "test"] }, "linter": { - "ignore": ["dist", "test", "scripts", "docs"], + "ignore": ["dist", "test", "scripts"], "enabled": true, "rules": { "recommended": true diff --git a/docs/package.json b/docs/package.json index 044ce662..a349f5f3 100644 --- a/docs/package.json +++ b/docs/package.json @@ -7,6 +7,9 @@ "build": "vocs build --searchIndex false && vocs search-index", "preview": "vocs preview" }, + "dependencies": { + "@effectai/sdk": "link:@effectai/sdk" + }, "devDependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/docs/pages/docs/collecting-data/create-a-campaign.mdx b/docs/pages/docs/collecting-data/create-a-campaign.mdx index 44b7bdaa..b0ca4512 100644 --- a/docs/pages/docs/collecting-data/create-a-campaign.mdx +++ b/docs/pages/docs/collecting-data/create-a-campaign.mdx @@ -6,38 +6,9 @@ A campaign is a collection of tasks that need to be completed by workers. ### Creating a campaign -```ts [example.ts] -import { createCampaign } from '@effectai/effect-js' +```ts twoslash +// [!include ~/snippets/tasks/create-campaign.ts] -// get the actor from the session -const { actor } = client.session - -// example template -const template = '...' - -const campaign = await createCampaign({ - client, - data: { - title: 'My first campaign', - category: 'Image Labeling', // Category of the campaign e.g. Image Labeling, Audio Transcription etc. - description: 'This is a description of my first campaign', // Description of the campaign - estimated_time: 3600, // Estimated time to complete a task in seconds - example_task: 'This is an example task', - image: 'https://example.com/image.png', - instructions: 'This is the instructions for the workers', - input_schema: null, - output_schema: null, - template, - version: 1, - }, - campaign: { - owner: actor, - reward: { quantity: '1', contract: 'effecttokens' }, - max_task_time: 3600, - qualis: [], - payer: actor, - }, -}) ``` -Wooooho! You have created your first campaign. You can now view the campaign on the [Effect Network](https://app.effect.network/campaigns) before you start collecting data, you need to add tasks to the campaign. You can do this by following the [Adding Tasks](/docs/collecting-data/adding-tasks) guide. \ No newline at end of file +Wooooho! You have created your first campaign. You can now view the campaign on the [Effect Network](https://app.effect.network/campaigns) before you start collecting data, you need to add tasks to the campaign. You can do this by following the [Adding Tasks](/docs/collecting-data/adding-tasks) guide. diff --git a/docs/pages/docs/getting-started.mdx b/docs/pages/docs/getting-started.mdx index 71093f34..52443d66 100644 --- a/docs/pages/docs/getting-started.mdx +++ b/docs/pages/docs/getting-started.mdx @@ -3,152 +3,79 @@ ## Installation Use your favorite package manager to install the SDK. +The sdk is available on [npm](https://www.npmjs.com/package/@effectai/sdk) - :::code-group +:::code-group - ```bash [npm] +```bash [npm] +npm i @effectai/sdk +``` - npm i @effectai/effect-js - ``` +```bash [bun] +bun i @effectai/sdk +``` - ```bash [bun] - bun i @effectai/effect-js - ``` +```bash [pnpm] +pnpm i @effectai/sdk +``` +::: - ```bash [pnpm] - pnpm i @effectai/effect-js - ``` - ::: ## Quick Start -### 1. Import the SDK +### 1. Import and Instantiate the EffectAI Client -```ts -import { createClient } from '@effectai/effect-js' -``` +Here the handy dandy `createClient` function is used to create a client instance. +It can three arguments, the first one is the network configuration, +the second one is the a session object, and the third one is the options object. -### 2. Instantiate the EffectAI Client +In this quick start guide we will be focusing on the first two, +how to get started with a non authenticated client using the network configuration and +an authenticated client using the session object. -Here the handy dandy `createClient` function is used to create a client instance. -It takes two optional arguments, the first one is the network configuration, the second one is the options object. You can read more about the options object in the [ClientOptions](#client-options) section. -```ts -// This would be ideal, the big question is if using mainnet should be explicitly passed or not. -const client = createClient() +Here is an example of how to create a client with a network configuration. -// But currently it is like this: -import { jungle4 } from '@effectai/effect-js' -// Atleast the opts ({}) object is now optional -const client = createClient(jungle4) +```ts twoslash +// [!include ~/snippets/getting-started/getting-started-init.ts] ``` -### 3. Interact with the Client - -The sdk is built using a stateless model, meaning that all the functions are pure and do not mutate the client object. -This means, that you need to creat one client, and you can pass that client as an argument to functions to make transactions. - -Here is an example of how to get the balance of an account, assuming that the client is already set up as described above. - -```ts -import { getVAccounts, getAccountById } from "@effectai/effect-js"; -import { Name } from "@wharfkit/antelope"; - -const actor = Name.from("forcedev1234"); -// Notice we are passing the clinet as an argument to the function. -const [vacc] = await getVAccounts({ client, actor }); - -console.log(vacc) -/** -{ - id: 24, - nonce: 0, - address: [ "name", "forcedev1234" ], - balance: { - quantity: "0.0000 EFX", - contract: "efxtoken1112", - }, -} -*/ + +### 2. Interact with the Client + +The sdk is built using a stateless model, meaning that all the functions are pure +and (almost) does not mutate the client object. +In practice this means that you wiil need to create a client object, +and pass it as an argument to the functions you want to use. + +Here is an example of how to retrieve an Effect account by using its ID. + +```ts twoslash +// [!include ~/snippets/getting-started/getting-started-nonauth.ts] ``` -### 4. Set up wallet and session +### 3. Set up wallet and session + +If you want to make transactions, such as creating a new account, creating a new tasks, +or transfering tokens, you need to set up a wallet and a session. +The wallet plugin is an interface that allows you to sign transactions and interact with the blockchain. -If you want to make transactions, such as creating a new account, creating a new tasks, or transfering tokens, you need to set up a wallet and a session. -The wallet plguin is an interface that allows you to sign transactions and interact with the blockchain. -The SDK comes with a few wallet plugins out of the box, but you can also create your own. +Currently the SDK does not come with any wallet plugins, +and you will need to use one provided by [wharfkit.com](https://wharfkit.com/). +A list of plugins can be found at [wharfkit.com/plugins](https://wharfkit.com/plugins?sort=popular) -In this example we will use the `WalletPluginPrivateKey` plugin, which requres a private key to be passed in. +In this example we will use the [`@wharfkit/wallet-plugin-privatekey`](https://wharfkit.com/plugins/wallet-plugin-privatekey) plugin, which requres a private key to be passed in. -Afterwards we can set up the Session object, which allows us to specify other parameters like the actor, permission, and the blockchain netork. +Afterwards we can set up the Session object, which allows us to specify other parameters like +the actor, permission, and the blockchain netork. Last but not least we connect the session to the client, and the client will be ready to use. -```ts -import { createBatch, createVAccount } from "@effectai/effect-js"; -import { Session } from "@wharfkit/session"; -import { WalletPluginPrivateKey } from "@wharfkit/wallet-plugin-privatekey" - -const walletPlugin = new WalletPluginPrivateKey("your_private_key_here") - -const session = new Session({ - actor: "forcedev1234", - permission: "active", - walletPlugin, - chain: { - id: jungle4.eosChainId, - url: jungle4.eosRpcUrl, - }, -}) - -// Connect the session to the client. -await session.setSession(session) - -// Now you can use the client to make authenticated transactions. -const account = Name.from("efxforce1112"); -await createVAccount({ client, account }); +```ts twoslash +// [!include ~/snippets/getting-started/getting-started-auth.ts] ``` -## Full example - -```ts -import { Session, Name } from "@wharfkit/session"; -import { WalletPluginPrivateKey } from "@wharfkit/wallet-plugin-privatekey"; -import { - createClient, - jungle4, - eos, // Use `eos` to use mainnet - getVAccounts, - createVAccount, -} from "@effectai/effect-js"; - -const client = createClient({ network: jungle4 }); - -// Make unauthenticated requests -const actor = Name.from("forcedev1234"); -const [vacc] = await getVAccounts({ client, actor }); - -// Set up wallet with privatekey -const walletPlugin = new WalletPluginPrivateKey("your_private_key_here"); - -// Set up session with wallet and chain -const session = new Session({ - actor: "forcedev1234", - permission: "active", - walletPlugin, - chain: { - id: jungle4.eosChainId, - url: jungle4.eosRpcUrl, - }, -}); - -// Connect session to client -await client.setSession(session); - -// Now you can use the client to make authenticated transactions. -const account = Name.from("efxforce1112"); -await createVAccount({ client, account }); -``` +## Conclusion Now that we have a basic understaning of how to set up the client, we can move on to more advanced topics. Read more on the following pages. diff --git a/docs/pages/docs/glossary/asset.mdx b/docs/pages/docs/glossary/asset.mdx new file mode 100644 index 00000000..b8636b02 --- /dev/null +++ b/docs/pages/docs/glossary/asset.mdx @@ -0,0 +1,21 @@ +# Asset + +## Description + +Some functions with the `@effectai/sdk` package will return a `Asset` object. +This object contains information about tokens on the blockchain and contain information such as the symbol, precision, and amount. + +An example for the `Asset` object is as follows: + + +```json +{ + "precision": 4, + "symbol": "EFX", + "units": 10000, + "value": 1 +} +``` + +Read more about the `Asset` object here: +https://wharfkit.com/docs/antelope/asset diff --git a/docs/pages/docs/glossary/clientOptions.mdx b/docs/pages/docs/glossary/client-options.mdx similarity index 100% rename from docs/pages/docs/glossary/clientOptions.mdx rename to docs/pages/docs/glossary/client-options.mdx diff --git a/docs/pages/docs/glossary/transaction-result.mdx b/docs/pages/docs/glossary/transaction-result.mdx new file mode 100644 index 00000000..c88e86d6 --- /dev/null +++ b/docs/pages/docs/glossary/transaction-result.mdx @@ -0,0 +1,26 @@ +# Transaction Result + +## Description + +Some functions with the `@effectai/sdk` package will return a `TransactionResult` object. +This object contains the transaction hash and the transaction receipt. + +The interface for the `TransactionResult` object is as follows: + + +```ts +interface TransactResult { + chain: ChainDefinition + request: SigningRequest + resolved: ResolvedSigningRequest | undefined + response?: { [key: string]: any } + revisions: TransactRevisions + signatures: Signature[] + signer: PermissionLevel + transaction: ResolvedTransaction | undefined +} +``` + +Read more about the `TransactionResult` object here: + +https://wharfkit.com/docs/session-kit/transact-result diff --git a/docs/pages/docs/tasks/batches/createBatch.mdx b/docs/pages/docs/tasks/batches/create-batch.mdx similarity index 100% rename from docs/pages/docs/tasks/batches/createBatch.mdx rename to docs/pages/docs/tasks/batches/create-batch.mdx diff --git a/docs/pages/docs/tasks/batches/getBatch.mdx b/docs/pages/docs/tasks/batches/get-batch.mdx similarity index 100% rename from docs/pages/docs/tasks/batches/getBatch.mdx rename to docs/pages/docs/tasks/batches/get-batch.mdx diff --git a/docs/pages/docs/tasks/campaigns/create-campaign.mdx b/docs/pages/docs/tasks/campaigns/create-campaign.mdx new file mode 100644 index 00000000..c4a7a869 --- /dev/null +++ b/docs/pages/docs/tasks/campaigns/create-campaign.mdx @@ -0,0 +1,65 @@ +# createCampaign + +## Description + +This function creates a campaign from a specified client with the given campaign parameters. +You can view the campaign on the [Effect Network](https://app.effect.network/campaigns) before you start collecting data, +you need to add tasks to the campaign. You can do this by following the [Adding Tasks](/docs/collecting-data/adding-tasks) guide. + +## Usage + +```ts twoslash +// [!include ~/snippets/tasks/create-campaign.ts] +``` +## Output + +```json +response: { + transaction_id: "9d321af28b7354c5cbee6ee956ea3e6590228b48539a9f0cafc6a8ca5ffe0ca2", + processed: { + id: "9d321af28b7354c5cbee6ee956ea3e6590228b48539a9f0cafc6a8ca5ffe0ca2", + block_num: 137520447, + block_time: "2024-05-01T03:55:31.500", + producer_block_id: null, + receipt: [Object ...], + elapsed: 4854, + net_usage: 176, + scheduled: false, + action_traces: [ + [Object ...] + ], + account_ram_delta: null, + except: null, + error_code: null, + }, +} +``` +## Parameters + + +### client +- **Type:** `SomeClient` +- **Description:** The client used to retrieve campaigns. + +### CreateCampaignArgs["campaign"] +- **version**: Version number of the campaign +- **maxTaskTime**: Time maximum time in seconds for the task +- **reward**: Reward for each task in EFX +- **title**: Title of the campaign +- **description**: Description of the campaign +- **instructions**: Instructions for the campaign +- **template**: Template for the campaign, which is a string of HTML +- **input_schema**: JSON schema for each input task +- **output_schema**: JSON schema for each output task +- **image**: Image URL for the campaign +- **category**: Category of the campaign +- **example_task**: An example_task for the campaign, this should be data that will be input into the campaign +- **estimated_time**: Estimated time in seconds for the task + +## Returns + +**Type:** TransactionResult + +**Description:** +Returns a transaction response object that contains the transaction id block number, and various properties that correlate to the transaction. +Read more about the transaction response here: [TransactionResponse](/docs/glossary/transaction-result.mdx) diff --git a/docs/pages/docs/tasks/reservations/getReservations.mdx b/docs/pages/docs/tasks/campaigns/get-all-campaigns.mdx similarity index 100% rename from docs/pages/docs/tasks/reservations/getReservations.mdx rename to docs/pages/docs/tasks/campaigns/get-all-campaigns.mdx diff --git a/docs/pages/docs/tasks/campaigns/get-campaign-by-id.mdx b/docs/pages/docs/tasks/campaigns/get-campaign-by-id.mdx new file mode 100644 index 00000000..429b3347 --- /dev/null +++ b/docs/pages/docs/tasks/campaigns/get-campaign-by-id.mdx @@ -0,0 +1,83 @@ + +# getCampaignById + +## Description + +This function retrieves a campaign from a specified client with the given ID. + +## Usage + + +```ts twoslash +// [!include ~/snippets/tasks/get-campaign-by-id.ts] + +``` + +## Output + +```json +{ + id: 1, + reservations_done: 1, + total_submissions: 2, + total_tasks: 1, + active_batch: 1, + num_batches: 1, + owner: [ "name", "efxefxefxefx" ], + paused: 0, + content: { + field_0: 0, + field_1: "QmVKwq3bYM6cPW6kstpiq4WYckWRtdfJnzAmms2iMyGqQg", + }, + max_task_time: 3600, + reward: { + quantity: "0.0100 EFX", + contract: "efxtoken1112", + }, + qualis: [], + info: { + version: 1.1, + title: "Labelstudio OCR (LAION)", + description: "You are contributing to a dataset for conversational style chatbots.", + instructions: "Instructions here...", + template: "

Template here...

", + input_schema: null, + output_schema: null, + image: null, + category: null, + example_task: null, + estimated_time: null, + }, +} +``` +## Parameters + +### client +- **Type:** `SomeClient` +- **Description:** The client used to retrieve campaigns. + +### id +- **Type:** `number` +- **Description:** The campaign id number of the campaign to retrieve. + +## Returns + +**Type:** [`Promise`](/docs/glossary/types#campaign) + +**Description:** A list of campaigns. + +**Properties:** + +- **id:** Campaign ID. +- **reservations_done:** Number of reservations done for the campaign. +- **total_submissions:** Total number of submissions for the campaign. +- **total_tasks:** Total number of tasks in the campaign. +- **active_batch:** Active batch number. +- **num_batches:** Total number of batches. +- **owner:** Owner of the campaign. +- **paused:** Indicator if the campaign is paused. +- **content:** Campaign content. +- **max_task_time:** Maximum task time in seconds. +- **reward:** Reward information. +- **qualis:** Qualification information. +- **info:** Additional information retrieved from IPFS. diff --git a/docs/pages/docs/tasks/campaigns/get-campaigns.mdx b/docs/pages/docs/tasks/campaigns/get-campaigns.mdx new file mode 100644 index 00000000..d784ce0d --- /dev/null +++ b/docs/pages/docs/tasks/campaigns/get-campaigns.mdx @@ -0,0 +1,82 @@ +# getCampaigns + +## Description + +This function retrieves campaigns from a specified client with optional parameters for pagination, sorting, and IPFS fetching. + +## Usage + +```ts twoslash +// [!include ~/snippets/tasks/get-campaigns.ts] +``` +## Output + +```json +{ + rows: [ + { + id: 0, + reservations_done: 2, + total_submissions: 2, + total_tasks: 6, + active_batch: 0, + num_batches: 2, + owner: [ "name", "efxefxefxefx" ], + paused: 0, + content: [Object ...], + max_task_time: 3600, + reward: [Object ...], + qualis: [], + info: [Object ...], + }, { */ ... /* }, { */ ... /* } + ], + next_key: UInt128 { */ ... /* }, + more: true, +} +``` + + +## Parameters + +### client +- **Type:** `SomeClient` +- **Description:** The client used to retrieve campaigns. + +### page +- **Type:** `number` +- **Description:** The page number of the campaigns to retrieve. Default is 1. + +### limit +- **Type:** `number` +- **Description:** The maximum number of campaigns to retrieve per page. Default is 20. + +### reverse +- **Type:** `boolean` +- **Description:** Whether to reverse the order of the retrieved campaigns. Default is false. + +### ipfsFetch +- **Type:** `boolean` +- **Description:** Whether to fetch additional information from IPFS for each campaign. Default is true. + + +## Returns + +- **Type:** [`Promise>`](/docs/glossary/types#campaign) +- **Description:** A list of campaigns. +- **Properties:** + - **rows:** An array of campaigns with the following structure: + - **id:** Campaign ID. + - **reservations_done:** Number of reservations done for the campaign. + - **total_submissions:** Total number of submissions for the campaign. + - **total_tasks:** Total number of tasks in the campaign. + - **active_batch:** Active batch number. + - **num_batches:** Total number of batches. + - **owner:** Owner of the campaign. + - **paused:** Indicator if the campaign is paused. + - **content:** Campaign content. + - **max_task_time:** Maximum task time in seconds. + - **reward:** Reward information. + - **qualis:** Qualification information. + - **info:** Additional information retrieved from IPFS if enabled. + - **next_key:** A string that can be used to fetch the next page of campaigns. + - **more:** A boolean indicating if there are more campaigns to fetch. diff --git a/docs/pages/docs/tasks/campaigns/getCampaigns.mdx b/docs/pages/docs/tasks/campaigns/getCampaigns.mdx deleted file mode 100644 index 9b00f9a5..00000000 --- a/docs/pages/docs/tasks/campaigns/getCampaigns.mdx +++ /dev/null @@ -1,36 +0,0 @@ -# Get Campaigns [Queries the Effect SDK API for a list of campaigns.] - -## Usage - -```ts [example.ts] -import { getCampaigns } from '@effectai/effect-js' - -const campaigns = await getCampaigns({ // [!code focus] - client, - limit: 10, - page: 1 -}); -``` - -## Returns - -- **Type:** [`Promise>`](/docs/glossary/types#campaign) -- **Description:** A list of campaigns. -- **Properties:** - - **rows:** An array of campaigns. - - **more:** A boolean indicating if there are more campaigns to fetch. - - **next_key:** A string that can be used to fetch the next page of campaigns. - -## Parameters - -### client -- **Type:** `Client` - -### limit (optional) -- **Type:** `number` -- **Default:** `10` - -### page (optional) -- **Type:** `number` -- **Default:** `1` - diff --git a/docs/pages/docs/tasks/get-acc-task-idx.mdx b/docs/pages/docs/tasks/get-acc-task-idx.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs/pages/docs/tasks/get-repetions.mdx b/docs/pages/docs/tasks/get-repetions.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs/pages/docs/tasks/get-submissions.mdx b/docs/pages/docs/tasks/get-submissions.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs/pages/docs/tasks/get-task.mdx b/docs/pages/docs/tasks/get-task.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs/pages/docs/tasks/reservations/get-reservations.mdx b/docs/pages/docs/tasks/reservations/get-reservations.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs/pages/docs/tasks/reservations/reserve-task.mdx b/docs/pages/docs/tasks/reservations/reserve-task.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs/pages/docs/tasks/submit-task.mdx b/docs/pages/docs/tasks/submit-task.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs/pages/docs/token/get-balance.mdx b/docs/pages/docs/token/get-balance.mdx new file mode 100644 index 00000000..4bd74da7 --- /dev/null +++ b/docs/pages/docs/token/get-balance.mdx @@ -0,0 +1,44 @@ +# getBalance + +## Description + +This function is used to get the balance of EFX of an Effect Network account on the EOS blockchain. +There is a difference between the balance of EFX of an account on the blockchain and the balance of EFX deposited in an Effect Account. +This function returns the balance of EFX on the blockchain. +Note the use of `balance.toString()` to convert the balance to a string. + + +## Usage + +```ts twoslash +// [!include ~/snippets/token/get-balance.ts] +``` + +## Output + +``` +"100.0000 EFX" +``` +## Parameters + +### Client +- **Type:** `Client` +- **Description:** Client object that is used to interact with the blockchain. + +### Actor + +- **Type:** `Name` +- **Description:** +The account name of the user for which the balance is to be fetched. +Note that the account name is a Name object that is created using the `Name.from` method. + +## Returns + +**Type:** Asset + +**Description:** +Returns the balance of the account in the form of an Asset object. +The asset object has properties that represent the amount and symbol of the balance of the user. +Note that the Asset object has a `toString` method that can be used to convert the balance to a string. + +You can read more about the: [`Asset` object](/docs/glossary/asset) diff --git a/docs/pages/docs/token/get-price.mdx b/docs/pages/docs/token/get-price.mdx new file mode 100644 index 00000000..ce7b6c53 --- /dev/null +++ b/docs/pages/docs/token/get-price.mdx @@ -0,0 +1,32 @@ +# getPrice + +## Description + +By calling this function, you will get the current price of the EFX token according to DefiBox. +The price is in USDT. The contract can be viewed at the following link: https://www.bloks.io/account/tethertether +It is not needed for this function to connect a client or a session. + + +## Usage + +```ts twoslash + +// [!include ~/snippets/token/get-price.ts] +``` + +## Output + +``` +0.023399935809187228 +``` +## Parameters + +### N.A. +- **Description:** No parameters required for this function + +## Returns + +**Type:** Number + +**Description:** The current price of the EFX token according to DefiBox in USDT. + diff --git a/docs/pages/docs/token/getPrice.mdx b/docs/pages/docs/token/getPrice.mdx deleted file mode 100644 index 0b119e12..00000000 --- a/docs/pages/docs/token/getPrice.mdx +++ /dev/null @@ -1,10 +0,0 @@ -# Get Price - -Get the current price of the EFX token according to DefiBox. - -```typescript -import { getPrice } from '@effectai/effect-js'; - -const price = await getPrice(); - -``` \ No newline at end of file diff --git a/docs/pages/docs/token/swap.mdx b/docs/pages/docs/token/swap.mdx new file mode 100644 index 00000000..abaaab4c --- /dev/null +++ b/docs/pages/docs/token/swap.mdx @@ -0,0 +1,175 @@ +# swap + +## Description + +This function is used to swap tokens from EFX to USDT or vice versa. +Note that the function requires a client object that is used to interact with the blockchain. +The client object also needs a Session object that is used to sign the transactions. + +### WalletPlugin + +Note that the `walletPlugin` object is used to sign the transactions. +The `walletPlugin` object is an instance of the WalletPluginPrivateKey class that is used to sign the transactions using the private key of the user. +Other wallet plugins can be used to sign transactions and can be found at: https://wharfkit.com/plugins + +## Usage + +```ts twoslash +// [!include ~/snippets/token/swap.ts] +``` + +## Output + +Read more about the transaction response here: [TransactionResponse](/docs/glossary/transaction-result.mdx) + +``` + response: { + transaction_id: "18c35c04fce3dbbfee0dea46707003c4897bb3c02766a69936c3ceb0bb836c99", + processed: { + id: "18c35c04fce3dbbfee0dea46707003c4897bb3c02766a69936c3ceb0bb836c99", + block_num: 137868012, + block_time: "2024-05-03T04:12:07.500", + producer_block_id: null, + receipt: { + status: "executed", + cpu_usage_us: 207, + net_usage_words: 16, + }, + elapsed: 207, + net_usage: 128, + scheduled: false, + action_traces: [ + { + action_ordinal: 1, + creator_action_ordinal: 0, + closest_unnotified_ancestor_action_ordinal: 0, + receipt: { + receiver: "efxaccount11", + act_digest: "d6f9be5af2565060d572a08f6e5f75498ea4c6a3d2cf77e26f3e3ffff4b6e244", + global_sequence: 196109234, + recv_sequence: 387, + auth_sequence: [ + [ "forcedev1234", 32 ] + ], + code_sequence: 8, + abi_sequence: 15, + }, + receiver: "efxaccount11", + act: { + account: "efxaccount11", + name: "vtransfer", + authorization: [ + { + actor: "forcedev1234", + permission: "active", + } + ], + data: { + from_id: 24, + to_id: 3, + quantity: { + quantity: "0.0001 EFX", + contract: "efxtoken1112", + }, + memo: "", + sig: null, + fee: null, + }, + hex_data: "180000000000000003000000000000000100000000000000044546580000000020420853419afb52000000", + }, + context_free: false, + elapsed: 76, + console: "", + trx_id: "18c35c04fce3dbbfee0dea46707003c4897bb3c02766a69936c3ceb0bb836c99", + block_num: 137868012, + block_time: "2024-05-03T04:12:07.500", + producer_block_id: null, + account_ram_deltas: [], + except: null, + error_code: null, + return_value_hex_data: "", + }, { + action_ordinal: 2, + creator_action_ordinal: 1, + closest_unnotified_ancestor_action_ordinal: 1, + receipt: { + receiver: "vibrantcacti", + act_digest: "d6f9be5af2565060d572a08f6e5f75498ea4c6a3d2cf77e26f3e3ffff4b6e244", + global_sequence: 196109235, + recv_sequence: 69, + auth_sequence: [ + [ "forcedev1234", 33 ] + ], + code_sequence: 8, + abi_sequence: 15, + }, + receiver: "vibrantcacti", + act: { + account: "efxaccount11", + name: "vtransfer", + authorization: [ + { + actor: "forcedev1234", + permission: "active", + } + ], + data: { + from_id: 24, + to_id: 3, + quantity: { + quantity: "0.0001 EFX", + contract: "efxtoken1112", + }, + memo: "", + sig: null, + fee: null, + }, + hex_data: "180000000000000003000000000000000100000000000000044546580000000020420853419afb52000000", + }, + context_free: false, + elapsed: 5, + console: "", + trx_id: "18c35c04fce3dbbfee0dea46707003c4897bb3c02766a69936c3ceb0bb836c99", + block_num: 137868012, + block_time: "2024-05-03T04:12:07.500", + producer_block_id: null, + account_ram_deltas: [], + except: null, + error_code: null, + return_value_hex_data: "", + } + ], + account_ram_delta: null, + except: null, + error_code: null, + }, + }, +} +``` +## Parameters + +### Client + +- **Type:** `Client` +- **Description:** Client object that is used to interact with the blockchain. Make sure that the client is connected with a Session. + +### Ammount + +- **Type:** `number` +- **Description:** +The amount of tokens to be swapped. + +### Direction + +- **Type:** `string` +- **Description:** +The direction of the swap. It can be either "UsdtToEfx" or "EfxToUsdt". + +## Returns + +**Type:** TransactionResponse + +**Description:** +Returns a transaction response object that contains the transaction id block number, and various properties that correlate to the transaction. +Read more about the transaction response here: [TransactionResponse](/docs/glossary/transaction-result.mdx) + diff --git a/docs/pages/docs/token/transfer.mdx b/docs/pages/docs/token/transfer.mdx new file mode 100644 index 00000000..a31071f4 --- /dev/null +++ b/docs/pages/docs/token/transfer.mdx @@ -0,0 +1,162 @@ +# VTransfer + +## Description + +Transfer EFX tokens from one vAccount to another. +Effect accounts are created so that users can interact with the Effect Network platform. +These accounts can be loaded with EFX tokens and used to pay for services on the platform. +This action allows users to transfer EFX tokens from one Effect account to another Effect account. + +## Usage + +```ts +// [!include ~/snippets/token/transfer.ts] +``` + +## Returns + +- **Type:** [`Promise>`](/docs/glossary/types#campaign) +- **Description:** A list of campaigns. +- **Properties:** + - **rows:** An array of campaigns. + - **more:** A boolean indicating if there are more campaigns to fetch. + - **next_key:** A string that can be used to fetch the next page of campaigns. + +## Parameters + +### client +- **Type:** `Client` + +### limit (optional) +- **Type:** `number` +- **Default:** `10` + +### page (optional) +- **Type:** `number` +- **Default:** `1` + +```json + // Response + response: { + transaction_id: "18c35c04fce3dbbfee0dea46707003c4897bb3c02766a69936c3ceb0bb836c99", + processed: { + id: "18c35c04fce3dbbfee0dea46707003c4897bb3c02766a69936c3ceb0bb836c99", + block_num: 137868012, + block_time: "2024-05-03T04:12:07.500", + producer_block_id: null, + receipt: { + status: "executed", + cpu_usage_us: 207, + net_usage_words: 16, + }, + elapsed: 207, + net_usage: 128, + scheduled: false, + action_traces: [ + { + action_ordinal: 1, + creator_action_ordinal: 0, + closest_unnotified_ancestor_action_ordinal: 0, + receipt: { + receiver: "efxaccount11", + act_digest: "d6f9be5af2565060d572a08f6e5f75498ea4c6a3d2cf77e26f3e3ffff4b6e244", + global_sequence: 196109234, + recv_sequence: 387, + auth_sequence: [ + [ "forcedev1234", 32 ] + ], + code_sequence: 8, + abi_sequence: 15, + }, + receiver: "efxaccount11", + act: { + account: "efxaccount11", + name: "vtransfer", + authorization: [ + { + actor: "forcedev1234", + permission: "active", + } + ], + data: { + from_id: 24, + to_id: 3, + quantity: { + quantity: "0.0001 EFX", + contract: "efxtoken1112", + }, + memo: "", + sig: null, + fee: null, + }, + hex_data: "180000000000000003000000000000000100000000000000044546580000000020420853419afb52000000", + }, + context_free: false, + elapsed: 76, + console: "", + trx_id: "18c35c04fce3dbbfee0dea46707003c4897bb3c02766a69936c3ceb0bb836c99", + block_num: 137868012, + block_time: "2024-05-03T04:12:07.500", + producer_block_id: null, + account_ram_deltas: [], + except: null, + error_code: null, + return_value_hex_data: "", + }, { + action_ordinal: 2, + creator_action_ordinal: 1, + closest_unnotified_ancestor_action_ordinal: 1, + receipt: { + receiver: "vibrantcacti", + act_digest: "d6f9be5af2565060d572a08f6e5f75498ea4c6a3d2cf77e26f3e3ffff4b6e244", + global_sequence: 196109235, + recv_sequence: 69, + auth_sequence: [ + [ "forcedev1234", 33 ] + ], + code_sequence: 8, + abi_sequence: 15, + }, + receiver: "vibrantcacti", + act: { + account: "efxaccount11", + name: "vtransfer", + authorization: [ + { + actor: "forcedev1234", + permission: "active", + } + ], + data: { + from_id: 24, + to_id: 3, + quantity: { + quantity: "0.0001 EFX", + contract: "efxtoken1112", + }, + memo: "", + sig: null, + fee: null, + }, + hex_data: "180000000000000003000000000000000100000000000000044546580000000020420853419afb52000000", + }, + context_free: false, + elapsed: 5, + console: "", + trx_id: "18c35c04fce3dbbfee0dea46707003c4897bb3c02766a69936c3ceb0bb836c99", + block_num: 137868012, + block_time: "2024-05-03T04:12:07.500", + producer_block_id: null, + account_ram_deltas: [], + except: null, + error_code: null, + return_value_hex_data: "", + } + ], + account_ram_delta: null, + except: null, + error_code: null, + }, + }, +} +``` diff --git a/docs/pages/docs/vaccount/claim.mdx b/docs/pages/docs/vaccount/claim.mdx new file mode 100644 index 00000000..75054196 --- /dev/null +++ b/docs/pages/docs/vaccount/claim.mdx @@ -0,0 +1,55 @@ +# claim + +## Description + +This function is used to claim the task reward that is locked in the escrow for the done tasks. +Every time a task is done, the reward is locked in the escrow until the timeout is reached. +After the timeout is reached, the reward can be claimed by the user who did the task. +The resulting EFX will be transferred to the user's VAccount. +The main difference between claim and payout, is where the funds are sent. + +## Usage + +```ts twoslash + +// [!include ~/snippets/vaccount/claim.ts] +``` + +## Output + +```json +response: { + transaction_id: "9d321af28b7354c5cbee6ee956ea3e6590228b48539a9f0cafc6a8ca5ffe0ca2", + processed: { + id: "9d321af28b7354c5cbee6ee956ea3e6590228b48539a9f0cafc6a8ca5ffe0ca2", + block_num: 137520447, + block_time: "2024-05-01T03:55:31.500", + producer_block_id: null, + receipt: [Object ...], + elapsed: 4854, + net_usage: 176, + scheduled: false, + action_traces: [ + [Object ...] + ], + account_ram_delta: null, + except: null, + error_code: null, + }, +} +``` + +## Parameters + +### Client +- **Description:** The client object, **must** be connected with a Session, so that only the user with their wallet can claim the rewards. + +## Returns + +**Type:** TransactionResult + +**Description:** +Returns a transaction response object that contains the transaction id block number, and various properties that correlate to the transaction. +Read more about the transaction response here: [TransactionResponse](/docs/glossary/transaction-result.mdx) + + diff --git a/docs/pages/docs/vaccount/create-account.mdx b/docs/pages/docs/vaccount/create-account.mdx new file mode 100644 index 00000000..4c3581a4 --- /dev/null +++ b/docs/pages/docs/vaccount/create-account.mdx @@ -0,0 +1,59 @@ +# createAccount + +## Description + +Next to having an EOS account, users will also need to create an Effect Network Virtual account, also known as a VAccount. +This virtual account is used to store the user's funds and is used to pay for services on the Effect Network. +The vAccount system is controled by the smart contract found at: [https://www.bloks.io/account/vaccount.efx](https://www.bloks.io/account/vaccount.efx) + +This function will create a new vAccount for the user, and will return the transaction response object. + + +## Usage + +```ts twoslash + +// [!include ~/snippets/vaccount/create-account.ts] +``` + +## Output + +```json +response: { + transaction_id: "9d321af28b7354c5cbee6ee956ea3e6590228b48539a9f0cafc6a8ca5ffe0ca2", + processed: { + id: "9d321af28b7354c5cbee6ee956ea3e6590228b48539a9f0cafc6a8ca5ffe0ca2", + block_num: 137520447, + block_time: "2024-05-01T03:55:31.500", + producer_block_id: null, + receipt: [Object ...], + elapsed: 4854, + net_usage: 176, + scheduled: false, + action_traces: [ + [Object ...] + ], + account_ram_delta: null, + except: null, + error_code: null, + }, +} +``` + +## Parameters + +### Client +- **Description:** The client object, **must** be connected with a Session. + +### Actor +- **Description:** The actor name, from which the PendinPayments should be claimed and paid out. + +## Returns + +**Type:** TransactionResult + +**Description:** +Returns a transaction response object that contains the transaction id block number, and various properties that correlate to the transaction. +Read more about the transaction response here: [TransactionResponse](/docs/glossary/transaction-result.mdx) + + diff --git a/docs/pages/docs/vaccount/deposit.mdx b/docs/pages/docs/vaccount/deposit.mdx new file mode 100644 index 00000000..fb23566e --- /dev/null +++ b/docs/pages/docs/vaccount/deposit.mdx @@ -0,0 +1,59 @@ +# deposit + +## Description + +User are able to deposit funds into their vAccount or claim the funds from escrow and have them deposited in to their vAccount. +Depositing funds into the vAccount is nessesary to be able to pay for creating campaigns, batches and tasks. + +## Usage + +```ts twoslash + +// [!include ~/snippets/vaccount/deposit.ts] +``` + +## Output + +```json +response: { + transaction_id: "9d321af28b7354c5cbee6ee956ea3e6590228b48539a9f0cafc6a8ca5ffe0ca2", + processed: { + id: "9d321af28b7354c5cbee6ee956ea3e6590228b48539a9f0cafc6a8ca5ffe0ca2", + block_num: 137520447, + block_time: "2024-05-01T03:55:31.500", + producer_block_id: null, + receipt: [Object ...], + elapsed: 4854, + net_usage: 176, + scheduled: false, + action_traces: [ + [Object ...] + ], + account_ram_delta: null, + except: null, + error_code: null, + }, +} +``` + +## Parameters + +### Client +- **Description:** The client object, **must** be connected with a Session. + +### vAccountId +- **Description:** The vAccount id, where the funds should be deposited. + + +### amount +- **Description:** The amount of funds to be deposited. + +## Returns + +**Type:** TransactionResult + +**Description:** +Returns a transaction response object that contains the transaction id block number, and various properties that correlate to the transaction. +Read more about the transaction response here: [TransactionResponse](/docs/glossary/transaction-result.mdx) + + diff --git a/docs/pages/docs/vaccount/get-accounts.mdx b/docs/pages/docs/vaccount/get-accounts.mdx new file mode 100644 index 00000000..50429ca3 --- /dev/null +++ b/docs/pages/docs/vaccount/get-accounts.mdx @@ -0,0 +1,57 @@ + +# getVaccounts + +## Description + +Next to having an EOS account, users will also need to create an Effect Network Virtual account, also known as a VAccount. +This virtual account is used to store the user's funds and is used to pay for services on the Effect Network. +The vAccount system is controled by the smart contract found at: [https://www.bloks.io/account/vaccount.efx](https://www.bloks.io/account/vaccount.efx) + +This function will return the vAccounts associated with the actor name provided. + + +## Usage + +```ts twoslash + +// [!include ~/snippets/vaccount/get-accounts.ts] +``` + +## Output + +```json +{ + id: 24, + nonce: 19, + address: [ "name", "forcedev1234" ], + balance: { + quantity: "2.0981 EFX", + contract: "efxtoken1112", + }, +} +``` + +## Parameters + +### Client +- **Description:** The client object, **must** be connected with a Session. + +### Actor +- **Description:** The actor name, from which the PendinPayments should be claimed and paid out. + +## Returns + +**Type:** Vaccount + +**Description:** +An object representing a Vaccount, containing the following fields: +- **id**: The id of the vAccount. +- **nonce**: The nonce of the vAccount. +- **address**: The address of the vAccount. +- **balance**: The balance of the vAccount, containing the following fields: + - **quantity**: The amount of EFX tokens in the vAccount. + - **contract**: The contract of the EFX tokens in the vAccount. + + + + diff --git a/docs/pages/docs/vaccount/get-avatar.mdx b/docs/pages/docs/vaccount/get-avatar.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs/pages/docs/vaccount/get-or-create.mdx b/docs/pages/docs/vaccount/get-or-create.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs/pages/docs/vaccount/get-pending-payments.mdx b/docs/pages/docs/vaccount/get-pending-payments.mdx new file mode 100644 index 00000000..63257e37 --- /dev/null +++ b/docs/pages/docs/vaccount/get-pending-payments.mdx @@ -0,0 +1,54 @@ +# getPendinPayments + +## Description + +Every time a user completes a task, EFX tokens are unlocked from the task, and put into escrow for the Vaccount. This function returns the pending payments for a given Vaccount. +Thus the Vaccount can claim the pending payments, and pay then out to the user when the unlock period has passed. + + +## Usage + +```ts twoslash +// [!include ~/snippets/vaccount/get-pending-payments.ts] +``` + +## Output + +```json +{ + pendingPayments: [], + claimablePayments: [], + totalEfxPending: 0, + totalEfxClaimable: 0, +} +``` + +## Parameters + +### Client +- **Description:** The client object, **must** be connected with a Session. + +### vAccountId +- **Description:** The id of the vAccount. + +## Returns + +**Type:** An object containing the following fields: + +- **pendingPayments** + - **Type:** Array of objects + - **Description:** An array of objects containing the pending payments for the Vaccount. + +- **claimablePayments** + - **Type:** Array of objects + - **Description:** An array of objects containing the claimable payments for the Vaccount. + +- **totalEfxPending** + - **Type:** Number + - **Description:** The total amount of EFX pending for the Vaccount. + +- **totalEfxClaimable** + - **Type:** Number + - **Description:** The total amount of EFX claimable for the Vaccount. + + diff --git a/docs/pages/docs/vaccount/payout.mdx b/docs/pages/docs/vaccount/payout.mdx new file mode 100644 index 00000000..e7966bde --- /dev/null +++ b/docs/pages/docs/vaccount/payout.mdx @@ -0,0 +1,59 @@ +# payout + +## Description + +This function is used to claim the task reward that is locked in the escrow for the done tasks. +Every time a task is done, the reward is locked in the escrow until the timeout is reached. +After the timeout is reached, the reward can be claimed by the user who did the task. +The resulting EFX will be transferred to the user's EOS account on the blockchain. + +The main difference between claim and payout, is where the funds are sent. + +## Usage + +```ts twoslash + +// [!include ~/snippets/vaccount/payout.ts] +``` + +## Output + +```json +response: { + transaction_id: "9d321af28b7354c5cbee6ee956ea3e6590228b48539a9f0cafc6a8ca5ffe0ca2", + processed: { + id: "9d321af28b7354c5cbee6ee956ea3e6590228b48539a9f0cafc6a8ca5ffe0ca2", + block_num: 137520447, + block_time: "2024-05-01T03:55:31.500", + producer_block_id: null, + receipt: [Object ...], + elapsed: 4854, + net_usage: 176, + scheduled: false, + action_traces: [ + [Object ...] + ], + account_ram_delta: null, + except: null, + error_code: null, + }, +} +``` + +## Parameters + +### Client +- **Description:** The client object, **must** be connected with a Session. + +### Actor +- **Description:** The actor name, from which the PendinPayments should be claimed and paid out. + +## Returns + +**Type:** TransactionResult + +**Description:** +Returns a transaction response object that contains the transaction id block number, and various properties that correlate to the transaction. +Read more about the transaction response here: [TransactionResponse](/docs/glossary/transaction-result.mdx) + + diff --git a/docs/pages/docs/vaccount/transfer.mdx b/docs/pages/docs/vaccount/transfer.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs/pages/docs/vaccount/withdraw.mdx b/docs/pages/docs/vaccount/withdraw.mdx new file mode 100644 index 00000000..87b656fc --- /dev/null +++ b/docs/pages/docs/vaccount/withdraw.mdx @@ -0,0 +1,56 @@ +# withdraw + +## Description + +User are able to deposit funds into their vAccount or claim the funds from escrow and have them deposited in to their vAccount. +These funds can be withdrawn to the user's wallet by calling the withdraw action. + + +## Usage + +```ts twoslash + +// [!include ~/snippets/vaccount/withdraw.ts] +``` + +## Output + +```json +response: { + transaction_id: "9d321af28b7354c5cbee6ee956ea3e6590228b48539a9f0cafc6a8ca5ffe0ca2", + processed: { + id: "9d321af28b7354c5cbee6ee956ea3e6590228b48539a9f0cafc6a8ca5ffe0ca2", + block_num: 137520447, + block_time: "2024-05-01T03:55:31.500", + producer_block_id: null, + receipt: [Object ...], + elapsed: 4854, + net_usage: 176, + scheduled: false, + action_traces: [ + [Object ...] + ], + account_ram_delta: null, + except: null, + error_code: null, + }, +} +``` + +## Parameters + +### Client +- **Description:** The client object, **must** be connected with a Session. + +### Actor +- **Description:** The actor name, from which the PendinPayments should be claimed and paid out. + +## Returns + +**Type:** TransactionResult + +**Description:** +Returns a transaction response object that contains the transaction id block number, and various properties that correlate to the transaction. +Read more about the transaction response here: [TransactionResponse](/docs/glossary/transaction-result.mdx) + + diff --git a/docs/sidebar.ts b/docs/sidebar.ts index 6f1859d3..a8c3391d 100644 --- a/docs/sidebar.ts +++ b/docs/sidebar.ts @@ -13,10 +13,7 @@ export const sidebar = { { text: "Collecting Data", items: [ - { - text: "Introduction", - link: "/docs/collecting-data/introduction", - }, + { text: "Introduction", link: "/docs/collecting-data/introduction" }, { text: "Creating a Template", link: "/docs/collecting-data/create-a-template", @@ -38,24 +35,75 @@ export const sidebar = { { text: "SDK API", items: [ + { + text: "vAccount", + items: [ + { text: "claim", link: "/docs/vaccount/claim" }, + { + text: "createAccount", + link: "/docs/vaccount/create-account", + }, + { text: "deposit", link: "/docs/vaccount/deposit" }, + { + text: "getVAccounts", + link: "/docs/vaccount/get-accounts", + }, + // { + // text: "TODO: getAvatar", + // link: "/docs/vaccount/get-avatar", + // }, + { + text: "getPendingPayments", + link: "/docs/vaccount/get-pending-payments", + }, + { text: "payout", link: "/docs/vaccount/payout" }, + { text: "withdraw", link: "/docs/vaccount/withdraw" }, + ], + }, { text: "Token", - items: [{ link: "/docs/token/getPrice", text: "getPrice" }], + items: [ + { text: "getPrice", link: "/docs/token/get-price" }, + { text: "getBalance", link: "/docs/token/get-balance" }, + { text: "transfer", link: "/docs/token/transfer" }, + { text: "swap", link: "/docs/token/swap" }, + ], }, { text: "Tasks", items: [ + { + text: "createCampaign", + link: "/docs/tasks/campaigns/create-campaign", + }, { text: "getCampaigns", - link: "/docs/tasks/campaigns/getCampaigns", + link: "/docs/tasks/campaigns/get-campaigns", + }, + { + text: "getCampaignById", + link: "/docs/tasks/campaigns/get-campaign-by-id", }, ], }, + // { + // text: "DAO", + // items: [ + // { + // text: "TODO: getAccountAssets", + // link: "/docs/tasks/dao/get-account-assets", + // }, + // ], + // }, ], }, { text: "Glossary", - items: [{ text: "Client Options", link: "/docs/glossary/clientOptions" }], + items: [ + { text: "Client Options", link: "/docs/glossary/client-options" }, + { text: "TransactResult", link: "/docs/glossary/transaction-result" }, + { text: "Asset", link: "/docs/glossary/asset" }, + ], }, { text: "FAQ", diff --git a/docs/snippets/client.ts b/docs/snippets/client.ts deleted file mode 100644 index 31df0f2b..00000000 --- a/docs/snippets/client.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createClient } from "@effectai/effect-js"; - -export const client = createClient({ - chain: mainnet, -}); diff --git a/docs/snippets/getting-started/getting-started-auth.ts b/docs/snippets/getting-started/getting-started-auth.ts new file mode 100644 index 00000000..da0b77fa --- /dev/null +++ b/docs/snippets/getting-started/getting-started-auth.ts @@ -0,0 +1,24 @@ +import { WalletPluginPrivateKey } from "@wharfkit/wallet-plugin-privatekey"; +import { + createClient, + jungle4 as network, + // eos as network , // Use `eos` to use mainnet + Session, + createVAccount, +} from "@effectai/sdk"; + +// Set up session with wallet and chain +const session = new Session({ + actor: "account_name_here", + permission: "permission_here", + walletPlugin: new WalletPluginPrivateKey("your_private_key_here"), + chain: network, +}); + +// 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 diff --git a/docs/snippets/getting-started/getting-started-init.ts b/docs/snippets/getting-started/getting-started-init.ts new file mode 100644 index 00000000..76eafb2e --- /dev/null +++ b/docs/snippets/getting-started/getting-started-init.ts @@ -0,0 +1,8 @@ +import { + createClient, + jungle4 as network, + // eos as network , // Use `eos` to use mainnet +} from "@effectai/sdk"; + +// Create client +const client = await createClient({ network }); diff --git a/docs/snippets/getting-started/getting-started-nonauth.ts b/docs/snippets/getting-started/getting-started-nonauth.ts new file mode 100644 index 00000000..29acfc68 --- /dev/null +++ b/docs/snippets/getting-started/getting-started-nonauth.ts @@ -0,0 +1,13 @@ +import { + createClient, + jungle4 as network, + // eos as network , // Use `eos` to use mainnet + getAccountById, +} from "@effectai/sdk"; + +// Create client to make unauthenticated transactions +const client = await createClient({ network }); + +// Retrieve data from Effect Network +const vAccount = await getAccountById({ client, accountId: 1 }); +console.log(vAccount); // => Account Details diff --git a/docs/snippets/tasks/create-campaign.ts b/docs/snippets/tasks/create-campaign.ts new file mode 100644 index 00000000..f01c0bcd --- /dev/null +++ b/docs/snippets/tasks/create-campaign.ts @@ -0,0 +1,35 @@ +import { WalletPluginPrivateKey } from "@wharfkit/wallet-plugin-privatekey"; +import { + createCampaign, + Session, + jungle4 as chain, + type CreateCampaignArgs, + createClient, +} from "@effectai/sdk"; + +const myNewCampaign: CreateCampaignArgs["campaign"] = { + version: 1.0, + maxTaskTime: 100, + reward: 3.5, + title: "Labelstudio OCR (LAION)", + description: "Description of the ttask here.", + instructions: "Some instructions here", + template: "

Template here

", + input_schema: null, + output_schema: null, + image: "", + category: "", + example_task: "", + estimated_time: 10, +}; + +const session = new Session({ + actor: "your-account", + permission: "permission-level", + chain, + walletPlugin: new WalletPluginPrivateKey("your-private-key"), +}); + +const client = await createClient({ session }); +const result = await createCampaign({ client, campaign: myNewCampaign }); +console.log(result); diff --git a/docs/snippets/tasks/get-campaign-by-id.ts b/docs/snippets/tasks/get-campaign-by-id.ts new file mode 100644 index 00000000..fc6dff59 --- /dev/null +++ b/docs/snippets/tasks/get-campaign-by-id.ts @@ -0,0 +1,10 @@ +import { + type Campaign, + type CampaignWithInfo, + createClient, + getCampaignById, + jungle4 as network, +} from "@effectai/sdk"; + +const client = await createClient({ network }); +const campaign = await getCampaignById({ client, id: 1 }); diff --git a/docs/snippets/tasks/get-campaigns.ts b/docs/snippets/tasks/get-campaigns.ts new file mode 100644 index 00000000..7c292bd3 --- /dev/null +++ b/docs/snippets/tasks/get-campaigns.ts @@ -0,0 +1,5 @@ +import { createClient, getCampaigns, jungle4 as network } from "@effectai/sdk"; + +const client = await createClient({ network }); +const campaigns = await getCampaigns({ client }); +console.log(campaigns); diff --git a/docs/snippets/token/get-balance.ts b/docs/snippets/token/get-balance.ts new file mode 100644 index 00000000..697184b4 --- /dev/null +++ b/docs/snippets/token/get-balance.ts @@ -0,0 +1,6 @@ +import { createClient, getBalance, jungle4 } from "@effectai/sdk"; + +const client = await createClient({ network: jungle4 }); +const actor = "forcedev1234"; +const balance = await getBalance({ client, actor }); +console.log(balance.toString()); diff --git a/docs/snippets/token/get-price.ts b/docs/snippets/token/get-price.ts new file mode 100644 index 00000000..206f7aab --- /dev/null +++ b/docs/snippets/token/get-price.ts @@ -0,0 +1,3 @@ +import { getPrice } from "@effectai/sdk"; +const price = await getPrice(); +console.log(price); diff --git a/docs/snippets/token/swap.ts b/docs/snippets/token/swap.ts new file mode 100644 index 00000000..3f3d6a42 --- /dev/null +++ b/docs/snippets/token/swap.ts @@ -0,0 +1,36 @@ +import { WalletPluginPrivateKey } from "@wharfkit/wallet-plugin-privatekey"; +import { + createClient, + jungle4 as chain, + // eos as chain, + Session, + swap, + type SwapArgs, + getBalance, +} from "@effectai/sdk"; + +const actor = "actor-name"; +const permission = "permission-level"; + +// Create a session +const session = new Session({ + chain, + actor, + permission, + walletPlugin: new WalletPluginPrivateKey("your_private_key"), +}); + +// Create client and connect session +const client = await createClient({ session }); + +// Define the swap arguments +const swapArgs: SwapArgs = { + client, + amount: 4, // Define amount, up to 4 digits behind the decimal + direction: "UsdtToEfx", // or "EfxToUsdt" +}; + +const preBalance = await getBalance({ client, actor }); + +// Call the swap function +const response = await swap(swapArgs); diff --git a/docs/snippets/token/transfer.ts b/docs/snippets/token/transfer.ts new file mode 100644 index 00000000..1341df50 --- /dev/null +++ b/docs/snippets/token/transfer.ts @@ -0,0 +1,20 @@ +import { + createClient, + jungle4 as network, + vTransfer, + getVAccounts, +} from "@effectai/sdk"; + +const client = await createClient({ network }); +const receiver = "receiver-account-name"; + +const [vAccountReceiver] = await getVAccounts({ + client, + actor: receiver, +}); + +const result = await vTransfer({ + client, + to_id: vAccountReceiver.id, + quantity: 12, +}); diff --git a/docs/snippets/vaccount/claim.ts b/docs/snippets/vaccount/claim.ts new file mode 100644 index 00000000..5c81aed5 --- /dev/null +++ b/docs/snippets/vaccount/claim.ts @@ -0,0 +1,38 @@ +import { WalletPluginPrivateKey } from "@wharfkit/wallet-plugin-privatekey"; +import { + createClient, + jungle4 as chain, + // eos as chain, + Session, + claim, + type ClaimArgs, + getPendingPayments, + getVAccounts, +} from "@effectai/sdk"; + +const actor = "actor-name"; +const permission = "permission-level"; + +// Create a session +const session = new Session({ + chain, + actor, + permission, + walletPlugin: new WalletPluginPrivateKey("your_private_key"), +}); + +// Create client and connect session +const client = await createClient({ session }); + +const [vacc] = await getVAccounts({ client, actor }); + +// Check pending payments +const pendingPayments = await getPendingPayments({ + client, + vAccountId: vacc.id, +}); + +// If there are claimable payments, claim them. +if (pendingPayments.totalEfxClaimable > 0) { + await claim({ client }); +} diff --git a/docs/snippets/vaccount/create-account.ts b/docs/snippets/vaccount/create-account.ts new file mode 100644 index 00000000..607b4745 --- /dev/null +++ b/docs/snippets/vaccount/create-account.ts @@ -0,0 +1,30 @@ +import { WalletPluginPrivateKey } from "@wharfkit/wallet-plugin-privatekey"; +import { + createClient, + jungle4 as chain, + // eos as chain, + Session, + createVAccount, + type CreateVAccountArgs, + getVAccounts, +} from "@effectai/sdk"; + +const actor = "actor-name"; +const permission = "permission-level"; + +// Create a session +const session = new Session({ + chain, + actor, + permission, + walletPlugin: new WalletPluginPrivateKey("your_private_key"), +}); + +// Create client and connect session +const client = await createClient({ session }); +const account = "account-name"; +const tx_result = await createVAccount({ client, account }); +console.log(tx_result); + +// Retrieve the created vaccount +const [vacc] = await getVAccounts({ client, actor: account }); diff --git a/docs/snippets/vaccount/deposit.ts b/docs/snippets/vaccount/deposit.ts new file mode 100644 index 00000000..5fd47e98 --- /dev/null +++ b/docs/snippets/vaccount/deposit.ts @@ -0,0 +1,12 @@ +import { + createClient, + jungle4 as network, + getVAccounts, + deposit, + type DepositArgs, +} from "@effectai/sdk"; + +const client = await createClient({ network }); +const actor = "account-name"; +const [vAccount] = await getVAccounts({ client, actor }); +const result = await deposit({ client, vAccountId: vAccount.id, amount: 0.1 }); diff --git a/docs/snippets/vaccount/get-accounts.ts b/docs/snippets/vaccount/get-accounts.ts new file mode 100644 index 00000000..52d98ab3 --- /dev/null +++ b/docs/snippets/vaccount/get-accounts.ts @@ -0,0 +1,14 @@ +import { + createClient, + jungle4 as network, + // eos as network, + getVAccounts, +} from "@effectai/sdk"; + +// Create client and connect session +const client = await createClient({ network }); + +const actor = "forcedev1234"; +// Retrieve the vAccounts +const [vacc] = await getVAccounts({ client, actor }); +console.log(vacc); diff --git a/docs/snippets/vaccount/get-pending-payments.ts b/docs/snippets/vaccount/get-pending-payments.ts new file mode 100644 index 00000000..85d2aa21 --- /dev/null +++ b/docs/snippets/vaccount/get-pending-payments.ts @@ -0,0 +1,21 @@ +import { + createClient, + jungle4 as network, + // eos as network, + getVAccounts, + getPendingPayments, +} from "@effectai/sdk"; + +// Create client and connect session +const client = await createClient({ network }); + +const actor = "forcedev1234"; +// Retrieve the vAccounts +const [vacc] = await getVAccounts({ client, actor }); + +const pendingPayments = await getPendingPayments({ + client, + vAccountId: vacc.id, +}); + +console.log(pendingPayments); diff --git a/docs/snippets/vaccount/payout.ts b/docs/snippets/vaccount/payout.ts new file mode 100644 index 00000000..c957237a --- /dev/null +++ b/docs/snippets/vaccount/payout.ts @@ -0,0 +1,38 @@ +import { WalletPluginPrivateKey } from "@wharfkit/wallet-plugin-privatekey"; +import { + createClient, + jungle4 as chain, + // eos as chain, + Session, + payout, + type PayoutArgs, + getPendingPayments, + getVAccounts, +} from "@effectai/sdk"; + +const actor = "actor-name"; +const permission = "permission-level"; + +// Create a session +const session = new Session({ + chain, + actor, + permission, + walletPlugin: new WalletPluginPrivateKey("your_private_key"), +}); + +// Create client and connect session +const client = await createClient({ session }); + +const [vacc] = await getVAccounts({ client, actor }); + +// Check pending payments, +// Not nessesary for this snippet, but helpful to know if there are any pending payments. +// This check is also already done in the payout function. +const pendingPayments = await getPendingPayments({ + client, + vAccountId: vacc.id, +}); + +// If there are claimable payments, claim and pay them out. +const result = await payout({ client, actor }); diff --git a/docs/snippets/vaccount/withdraw.ts b/docs/snippets/vaccount/withdraw.ts new file mode 100644 index 00000000..35fe6181 --- /dev/null +++ b/docs/snippets/vaccount/withdraw.ts @@ -0,0 +1,31 @@ +import { WalletPluginPrivateKey } from "@wharfkit/wallet-plugin-privatekey"; +import { + createClient, + jungle4 as chain, + // eos as chain, + Session, + withdraw, + type WithdrawArgs, + getVAccounts, +} from "@effectai/sdk"; + +const actor = "actor-name"; +const permission = "permission-level"; + +// Create a session +const session = new Session({ + chain, + actor, + permission, + walletPlugin: new WalletPluginPrivateKey("your_private_key"), +}); + +// Create client and connect session +const client = await createClient({ session }); + +// Retrieve user balance +const [vacc] = await getVAccounts({ client, actor }); +console.log(vacc.balance); + +// If there are claimable payments, claim and pay them out. +const result = await withdraw({ client, quantity: 42 }); diff --git a/package.json b/package.json index f0fe331d..d06e1d81 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "scripts": { "test": "bun --env-file=.env test", "test:watch": "bun --env-file=.env test --watch", + "test:only": "bun --env-file=.env test --watch --only", "test:coverage": "bun --env-file=.env test --coverage", "dev": "tsc -w", "build": "tsc --module es2020", @@ -19,7 +20,7 @@ "changeset": "changeset", "changeset:public": "bun scripts/updateVersion.ts && bun build && changeset publish", "changeset:version": "changeset version && bun install --frozen-lockfile && bun scripts/updateVersion.ts", - "docs:dev": "cd docs && bun run dev", + "docs:dev": "bun link && cd docs && bun run dev", "docs:build": "cd docs && bun run build", "docs:preview": "cd docs && bun run preview" }, diff --git a/src/@generated/types/efxaccount11.ts b/src/@generated/types/efxaccount11.ts index ee744172..bede5231 100644 --- a/src/@generated/types/efxaccount11.ts +++ b/src/@generated/types/efxaccount11.ts @@ -1,8 +1,5 @@ import type { - BytesType, Checksum160, - Checksum160Type, - UInt64, ExtendedSymbol, Signature, } from "@wharfkit/antelope"; diff --git a/src/actions/atomic/getAccountAssets.ts b/src/actions/atomic/getAccountAssets.ts index 6f0fab18..b16ab5d7 100644 --- a/src/actions/atomic/getAccountAssets.ts +++ b/src/actions/atomic/getAccountAssets.ts @@ -1,10 +1,10 @@ -import type { Name, UInt32 } from "@wharfkit/antelope"; +import type { NameType, UInt32 } from "@wharfkit/antelope"; import type { Client } from "../../client"; import type { GetTableRowsResponse } from "../../exports"; export type getAccountAssetsArgs = { client: Client; - account: Name; + account: NameType; }; // TODO: What does this comment mean? diff --git a/src/actions/dao/getAvatar.ts b/src/actions/dao/getAvatar.ts index c5e9fc0f..1d305334 100644 --- a/src/actions/dao/getAvatar.ts +++ b/src/actions/dao/getAvatar.ts @@ -6,6 +6,7 @@ export type GetAvatarArgs = { account: string; }; +// TODO: This does not seem to be working as expected export const getAvatar = async ({ client, account }: GetAvatarArgs) => { const { dao } = useEFXContracts(client); const { provider } = client; diff --git a/src/actions/tasks/batch/createBatch.test.ts b/src/actions/tasks/batch/createBatch.test.ts new file mode 100644 index 00000000..c1500931 --- /dev/null +++ b/src/actions/tasks/batch/createBatch.test.ts @@ -0,0 +1,48 @@ +import { expect, test, describe } from "bun:test"; +import { testClientSession } from "../../../../test/src/utils"; +import { + createBatch, + getBatchById, + getCampaignById, + getIpfsResource, +} from "../../../exports"; + +describe("getAvatar", async () => { + test.todo("Should create a new batch for given campaign", async () => { + const campaignId = 1; + const client = await testClientSession(); + const preCampaign = await getCampaignById({ client, id: campaignId }); + + const batch = await getBatchById({ client, id: preCampaign.active_batch }); + + const batchData = await getIpfsResource({ + client, + hash: batch.content.field_1, + }); + + const taskData: Record = { + "e20bb19f-ca14-4575-8c14-1916896cb2f3": "Random question here", + "35921e43-f058-4214-88e8-062a7eebe878": "Random answer here", + "ba1865eb-6a52-4e06-9a64-ed351cf3f2e2": "Other question here", + "b9d1a1f7-3b4f-4c7b-9b5d-3f0b3b7d4b9e": "Other answer here", + }; + + const response = await createBatch({ + client, + campaignId, + reward: 1, + repetitions: 1, + taskData, + }); + + expect(response).toBeDefined(); + + const postCampaign = await getCampaignById({ client, id: campaignId }); + expect(postCampaign.num_batches).toBeGreaterThan(preCampaign.num_batches); + }); + + test.todo("Should fail when ...", async () => { + // TODO: Should fail when there isn't enough funds, or session connected. + // Figure out flow to test this + }); +}); diff --git a/src/actions/tasks/batch/createBatch.ts b/src/actions/tasks/batch/createBatch.ts index 3bc39712..4de4b695 100644 --- a/src/actions/tasks/batch/createBatch.ts +++ b/src/actions/tasks/batch/createBatch.ts @@ -107,7 +107,7 @@ export const createBatch = async ({ } const campaign = await getCampaignById({ client, id: campaignId }); - const assetQuantity = Asset.from(reward, " EFX"); + const assetQuantity = Asset.from(reward, "4,EFX"); const batchPrice = assetQuantity.value * repetitions; // Check if the user has enough funds to pay for the batch diff --git a/src/actions/tasks/batch/getBatch.test.ts b/src/actions/tasks/batch/getBatch.test.ts new file mode 100644 index 00000000..6873d8dd --- /dev/null +++ b/src/actions/tasks/batch/getBatch.test.ts @@ -0,0 +1,26 @@ +import { expect, test, describe } from "bun:test"; +import { testClientSession } from "../../../../test/src/utils"; +import { getBatchById, getCampaignById } from "../../../exports"; + +describe("getAvatar", async () => { + test("Should create a new batch for given campaign", async () => { + const campaignId = 1; + const client = await testClientSession(); + const campaign = await getCampaignById({ client, id: campaignId }); + const batchById = await getBatchById({ + client, + id: campaign.active_batch, + }); + + const batch = await getBatchById({ client, id: batchById.id }); + expect(batch).toBeDefined(); + expect(batch.id).toBe(batchById.id); + }); + + test("Should return undefined if batch does not exist.", async () => { + const nonExistentBatchId = 999999999; + const client = await testClientSession(); + const batch = await getBatchById({ client, id: nonExistentBatchId }); + expect(batch).toBeUndefined(); + }); +}); diff --git a/src/actions/tasks/campaigns/createCampaign.test.ts b/src/actions/tasks/campaigns/createCampaign.test.ts index b3b3532b..d3a12984 100644 --- a/src/actions/tasks/campaigns/createCampaign.test.ts +++ b/src/actions/tasks/campaigns/createCampaign.test.ts @@ -23,7 +23,7 @@ const myNewCampaign: CreateCampaignArgs["campaign"] = { describe("createCampaign", async () => { test("createCampaign() should throw an error", async () => { - const client = createClient({ network: jungle4 }); + const client = await createClient({ network: jungle4 }); expect(async () => { await createCampaign({ client, @@ -33,29 +33,8 @@ describe("createCampaign", async () => { }); test.skip("createCampaign() should create a new campaign", async () => { - const client = await testClientSession({ testEnvNetwork: jungle4 }); + const client = await testClientSession(); const result = await createCampaign({ client, campaign: myNewCampaign }); expect(result).toBeDefined(); - /** - * response: { - * transaction_id: "9d321af28b7354c5cbee6ee956ea3e6590228b48539a9f0cafc6a8ca5ffe0ca2", - * processed: { - * id: "9d321af28b7354c5cbee6ee956ea3e6590228b48539a9f0cafc6a8ca5ffe0ca2", - * block_num: 137520447, - * block_time: "2024-05-01T03:55:31.500", - * producer_block_id: null, - * receipt: [Object ...], - * elapsed: 4854, - * net_usage: 176, - * scheduled: false, - * action_traces: [ - * [Object ...] - * ], - * account_ram_delta: null, - * except: null, - * error_code: null, - * }, - * } - */ }); }); diff --git a/src/actions/tasks/campaigns/getAllCampaigns.test.ts b/src/actions/tasks/campaigns/getAllCampaigns.test.ts index f8b27cdd..6f1de316 100644 --- a/src/actions/tasks/campaigns/getAllCampaigns.test.ts +++ b/src/actions/tasks/campaigns/getAllCampaigns.test.ts @@ -6,7 +6,7 @@ import { jungle4 } from "../../../exports"; describe("getAllCampaigns", async () => { test("getAllCampaigns() should retrieve all campaign", async () => { - const client = createClient({ network: jungle4 }); + const client = await createClient({ network: jungle4 }); const campaigns = await getAllCampaigns({ client }); expect(campaigns).toBeDefined(); expect(campaigns).toBeArray(); diff --git a/src/actions/tasks/campaigns/getCampaignById.test.ts b/src/actions/tasks/campaigns/getCampaignById.test.ts index d4eaaefb..518d23e3 100644 --- a/src/actions/tasks/campaigns/getCampaignById.test.ts +++ b/src/actions/tasks/campaigns/getCampaignById.test.ts @@ -6,7 +6,7 @@ import { campaign as exampleCampaign } from "../../../../test/src/constants"; describe("getCampaignById", async () => { test("getCampaignById() should throw an error when accessing unretrievable id", async () => { - const client = createClient({ network: jungle4 }); + const client = await createClient({ network: jungle4 }); const id = 11111; expect(async () => { await getCampaignById({ client, id }); @@ -14,7 +14,7 @@ describe("getCampaignById", async () => { }); test("getCampaignById() should retrieve campaign on testnet", async () => { - const client = createClient({ network: jungle4 }); + const client = await createClient({ network: jungle4 }); const id = 1; const campaign = await getCampaignById({ client, id }); expect(campaign).toBeDefined(); diff --git a/src/actions/tasks/campaigns/getCampaigns.test.ts b/src/actions/tasks/campaigns/getCampaigns.test.ts index 7a4a9b38..a6f9b8f5 100644 --- a/src/actions/tasks/campaigns/getCampaigns.test.ts +++ b/src/actions/tasks/campaigns/getCampaigns.test.ts @@ -1,11 +1,10 @@ import { describe, test, expect } from "bun:test"; import { testClientSession } from "../../../../test/src/utils"; import { getCampaigns } from "./getCampaigns"; -import { jungle4 } from "../../../exports"; describe("getCampaigns", async () => { test("getCampaigns() should return 3 campaigns", async () => { - const client = await testClientSession({ testEnvNetwork: jungle4 }); + const client = await testClientSession(); const campaigns = await getCampaigns({ client, limit: 3 }); expect(campaigns).toBeDefined(); expect(campaigns.rows).toBeArray(); diff --git a/src/actions/tasks/getAccTaskIdx.test.ts b/src/actions/tasks/getAccTaskIdx.test.ts new file mode 100644 index 00000000..7fca2c0d --- /dev/null +++ b/src/actions/tasks/getAccTaskIdx.test.ts @@ -0,0 +1,26 @@ +import { expect, test, describe } from "bun:test"; +import { destructureEnv, testClientSession } from "../../../test/src/utils"; +import { getAccTaskIdx, getVAccounts } from "../../exports"; + +describe("getAccountTaskIndex", async () => { + test("Should return an array", async () => { + const client = await testClientSession(); + const { actor } = destructureEnv(); + const [vacc] = await getVAccounts({ client, actor }); + + const accTaskIdx = await getAccTaskIdx({ client, accountId: vacc.id }); + expect(accTaskIdx).toBeDefined(); + expect(accTaskIdx).toBeArray(); + }); + + test.todo( + "Should return a value within the array when reserving task", + async () => { + // TODO: Implement this test + // Figure out flow of reserving a task, + // retrieving the task index, + // verifying the task index and + // submitting the task to complete the cycle. + }, + ); +}); diff --git a/src/actions/tasks/getForceSettings.test.ts b/src/actions/tasks/getForceSettings.test.ts new file mode 100644 index 00000000..f883ba96 --- /dev/null +++ b/src/actions/tasks/getForceSettings.test.ts @@ -0,0 +1,21 @@ +import { expect, test, describe } from "bun:test"; +import { testClientSession } from "../../../test/src/utils"; +import { getForceSettings } from "../../exports"; + +describe("getForceSettings", async () => { + const settingsExample = { + vaccount_contract: "efxaccount11", + force_vaccount_id: 11, + payout_delay_sec: 1800, + release_task_delay_sec: 1800, + fee_contract: "efxfeepool11", + fee_percentage: "0.10000000149011612", + }; + + test("Should match config settings", async () => { + const client = await testClientSession(); + const settings = await getForceSettings({ client }); + expect(settings).toBeDefined(); + expect(Object.keys(settings)).toEqual(Object.keys(settingsExample)); + }); +}); diff --git a/src/actions/tasks/getForceSettings.ts b/src/actions/tasks/getForceSettings.ts index 5e713930..e7fb2dec 100644 --- a/src/actions/tasks/getForceSettings.ts +++ b/src/actions/tasks/getForceSettings.ts @@ -8,12 +8,12 @@ export type GetForceSettingsArgs = { export const getForceSettings = async ({ client }: GetForceSettingsArgs) => { const { provider, network } = client; - const { contracts } = network.config.efx; + const { tasks } = network.config.efx.contracts; try { const response = (await provider.v1.chain.get_table_rows({ - code: contracts.tasks, - scope: contracts.tasks, + code: tasks, + scope: tasks, table: "settings", })) as GetTableRowsResponse; diff --git a/src/actions/tasks/getRepetitions.test.ts b/src/actions/tasks/getRepetitions.test.ts new file mode 100644 index 00000000..53addfa5 --- /dev/null +++ b/src/actions/tasks/getRepetitions.test.ts @@ -0,0 +1,12 @@ +import { expect, test, describe } from "bun:test"; +import { testClientSession } from "../../../test/src/utils"; +import { getRepetitions } from "../../exports"; + +describe("getRepetitions", async () => { + test("Should retrieve the repitions as array", async () => { + const client = await testClientSession(); + const repitions = await getRepetitions({ client }); + expect(repitions).toBeDefined(); + expect(repitions).toBeArray(); + }); +}); diff --git a/src/actions/tasks/getRepetitions.ts b/src/actions/tasks/getRepetitions.ts index 6fde6571..0ffd96f7 100644 --- a/src/actions/tasks/getRepetitions.ts +++ b/src/actions/tasks/getRepetitions.ts @@ -1,7 +1,11 @@ import type { Client } from "../../client"; import { useEFXContracts } from "../../utils/state"; -export const getRepetitions = async (client: Client) => { +export type GetRepetitionsArgs = { + client: Client; +}; + +export const getRepetitions = async ({ client }: GetRepetitionsArgs) => { try { const { tasks } = useEFXContracts(client); const { provider } = client; diff --git a/src/actions/tasks/getSubmissions.test.ts b/src/actions/tasks/getSubmissions.test.ts new file mode 100644 index 00000000..c0d61d89 --- /dev/null +++ b/src/actions/tasks/getSubmissions.test.ts @@ -0,0 +1,32 @@ +import { expect, test, describe } from "bun:test"; +import { testClientSession } from "../../../test/src/utils"; +import { getSubmissions } from "../../exports"; + +describe("getSubmissions", async () => { + const submissionExample = { + id: 37, + campaign_id: 6, + task_idx: 0, + account_id: 12, + content: null, + batch_id: "25769803776", + data: { + first: 1, + second: + "426624b24a7703d02c5797020c46dc10d573171c77b6eca915311ecb1820700c126f", + }, + paid: 0, + submitted_on: "2024-05-04T20:39:30", + }; + + test("Should get submissions", async () => { + const client = await testClientSession(); + const submissions = await getSubmissions({ client, reverse: false }); + + expect(submissions).toBeDefined(); + expect(submissions).toBeArray(); + + const [submission] = submissions; + expect(Object.keys(submission)).toEqual(Object.keys(submissionExample)); + }); +}); diff --git a/src/actions/tasks/getSubmissions.ts b/src/actions/tasks/getSubmissions.ts index 1d419fea..4851a37f 100644 --- a/src/actions/tasks/getSubmissions.ts +++ b/src/actions/tasks/getSubmissions.ts @@ -12,7 +12,7 @@ export type GetSubmissionsArgs = { export const getSubmissions = async ({ client, reverse = false, -}: GetSubmissionsArgs) => { +}: GetSubmissionsArgs): Promise => { try { const { provider } = client; const { tasks } = useEFXContracts(client); @@ -24,7 +24,9 @@ export const getSubmissions = async ({ reverse, })) as GetTableRowsResponse; - return data; + const { rows } = data; + + return rows; } catch (e) { console.error("Error while fetching tasks:", e); throw new Error("Failed to fetch tasks"); diff --git a/src/actions/tasks/getTask.test.ts b/src/actions/tasks/getTask.test.ts new file mode 100644 index 00000000..5ab1bcf5 --- /dev/null +++ b/src/actions/tasks/getTask.test.ts @@ -0,0 +1,27 @@ +import { expect, test, describe } from "bun:test"; +import { testClientSession } from "../../../test/src/utils"; +import { + getAccTaskIdx, + getBatchById, + getCampaignById, + getTaskData, +} from "../../exports"; + +describe("getTask", async () => { + test("Should get task", async () => { + const client = await testClientSession(); + const campaignById = await getCampaignById({ client, id: 1 }); + const batchById = await getBatchById({ + client, + id: campaignById.active_batch, + }); + const taskIndex = batchById.start_task_idx; + + const taskData = await getTaskData({ + client, + taskIndex, + batchId: batchById.id, + }); + expect(taskData).toBeDefined(); + }); +}); diff --git a/src/actions/tasks/reservations/getReservations.test.ts b/src/actions/tasks/reservations/getReservations.test.ts new file mode 100644 index 00000000..2ea36e40 --- /dev/null +++ b/src/actions/tasks/reservations/getReservations.test.ts @@ -0,0 +1,61 @@ +import { expect, test, describe } from "bun:test"; +import { destructureEnv, testClientSession } from "../../../../test/src/utils"; +import { + getReservations, + getReservationForCampaign, + getReservationsForVAccount, + getReservationsForCampaign, +} from "./getReservations"; +import { getVAccounts } from "../../vaccount/getAccounts"; + +describe("getReservation", async () => { + test("Should return an array, with getReservations()", async () => { + const client = await testClientSession(); + const reservation = await getReservations({ client }); + + expect(reservation).toBeDefined(); + expect(reservation).toBeArray(); + }); + + test("Should get reservation for vAccount", async () => { + const client = await testClientSession(); + const { actor } = destructureEnv(); + const [vacc] = await getVAccounts({ client, actor }); + + const reservation = await getReservationsForVAccount({ + client, + vAccountId: vacc.id, + }); + + expect(reservation).toBeDefined(); + expect(reservation).toBeArray(); + }); + + test("Should get reservation for Campaigns", async () => { + const client = await testClientSession(); + const reservation = await getReservationsForCampaign({ + client, + campaignId: 1, + }); + + expect(reservation).toBeDefined(); + expect(reservation).toBeArray(); + }); + + // TODO: Sometimes the user will not have a reservation, so we need to make sure that + // a reservation is created before running this test. + test.todo("Should get reservation for Campaign by vAccountId", async () => { + const client = await testClientSession(); + const { actor } = destructureEnv(); + const [vacc] = await getVAccounts({ client, actor }); + + const reservation = await getReservationForCampaign({ + client, + vAccountId: vacc.id, + campaignId: 1, + }); + + expect(reservation).toBeDefined(); + expect(reservation).toBeArray(); + }); +}); diff --git a/src/actions/tasks/reservations/getReservations.ts b/src/actions/tasks/reservations/getReservations.ts index ba4f1cb1..4adaba1b 100644 --- a/src/actions/tasks/reservations/getReservations.ts +++ b/src/actions/tasks/reservations/getReservations.ts @@ -17,10 +17,10 @@ export const getReservations = async ({ lowerBound, upperBound, indexPosition = "secondary", -}: GetReservationsArgs) => { +}: GetReservationsArgs): Promise => { const { tasks } = useEFXContracts(client); - return (await client.provider.v1.chain.get_table_rows({ + const response = (await client.provider.v1.chain.get_table_rows({ scope: tasks, code: tasks, table: "reservation", @@ -28,6 +28,9 @@ export const getReservations = async ({ upper_bound: upperBound, lower_bound: lowerBound, })) as GetTableRowsResponse; + + const { rows } = response; + return rows; }; export type GetReservationsForCampaignArgs = { @@ -38,12 +41,11 @@ export type GetReservationsForCampaignArgs = { export const getReservationsForCampaign = async ({ client, campaignId, -}: GetReservationsForCampaignArgs) => { +}: GetReservationsForCampaignArgs): Promise => { try { const lowerBound = createCompositeU64Key(campaignId, 0); const upperBound = createCompositeU64Key(campaignId, Number(UInt32.max)); - const { rows } = await getReservations({ client, lowerBound, upperBound }); - return rows; + return await getReservations({ client, lowerBound, upperBound }); } catch (e) { console.error(e); throw e; @@ -58,18 +60,16 @@ export type GetReservationForVAccountArgs = { export const getReservationsForVAccount = async ({ client, vAccountId, -}: GetReservationForVAccountArgs) => { +}: GetReservationForVAccountArgs): Promise => { try { if (!vAccountId) throw new Error("vAccountId is required"); - const data = await getReservations({ + return await getReservations({ client, lowerBound: UInt64.from(vAccountId), upperBound: UInt64.from(vAccountId), indexPosition: "fourth", }); - - return data.rows; } catch (e) { console.error(e); throw e; @@ -82,11 +82,12 @@ export type GetReservationForCampaignArgs = { vAccountId: number; }; +// TODO: This function name is unclear, we should rename it to: getVAccountReservationForCampaign export const getReservationForCampaign = async ({ client, campaignId, vAccountId, -}: GetReservationForCampaignArgs) => { +}: GetReservationForCampaignArgs): Promise => { try { const bound = createCompositeU64Key(campaignId, vAccountId); const data = await getReservations({ @@ -95,7 +96,8 @@ export const getReservationForCampaign = async ({ upperBound: bound, }); - return data.rows[0]; + const [reservation] = data; + return reservation; } catch (e) { console.error(e); throw e; diff --git a/src/actions/tasks/reservations/reserveTask.test.ts b/src/actions/tasks/reservations/reserveTask.test.ts new file mode 100644 index 00000000..193dd87f --- /dev/null +++ b/src/actions/tasks/reservations/reserveTask.test.ts @@ -0,0 +1,14 @@ +import { expect, test, describe } from "bun:test"; +import { testClientSession } from "../../../../test/src/utils"; +import { reserveTask } from "./reserveTask"; + +describe("reserveTask", async () => { + // TODO: Figure out flow for how to test this function + test.todo("Should reserve task", async () => { + const client = await testClientSession(); + + const reservation = await reserveTask({ client, campaignId: 1 }); + + expect(reservation).toBeDefined(); + }); +}); diff --git a/src/actions/tasks/submitTask.test.ts b/src/actions/tasks/submitTask.test.ts new file mode 100644 index 00000000..76fa372e --- /dev/null +++ b/src/actions/tasks/submitTask.test.ts @@ -0,0 +1,24 @@ +import { expect, test, describe } from "bun:test"; +import { destructureEnv, testClientSession } from "../../../test/src/utils"; +import { submitTask } from "./submitTask"; +import { getReservationForCampaign } from "./reservations/getReservations"; +import { getVAccounts } from "../vaccount/getAccounts"; + +describe("submitTask", async () => { + // TODO: Figure out flow for how to test this function + test.todo("Should submitTask", async () => { + const client = await testClientSession(); + const { actor } = destructureEnv(); + const [vAccount] = await getVAccounts({ client, actor }); + + const reservation = await getReservationForCampaign({ + client, + campaignId: 1, + vAccountId: vAccount.id, + }); + + const response = await submitTask({ client, reservation, data: {} }); + + expect(response).toBeDefined(); + }); +}); diff --git a/src/actions/token/getBalance.test.ts b/src/actions/token/getBalance.test.ts index be30dd39..207d1645 100644 --- a/src/actions/token/getBalance.test.ts +++ b/src/actions/token/getBalance.test.ts @@ -2,12 +2,11 @@ import { describe, test, expect } from "bun:test"; import { getBalance } from "./getBalance"; import { createClient } from "../../client"; import { eos, jungle4 } from "../../exports"; -import { Name } from "@wharfkit/antelope"; describe("getBalance", async () => { test("getBalance() should retrieve balance from user on mainnet", async () => { - const client = createClient({ network: jungle4 }); - const actor = Name.from("forcedev1234"); + const client = await createClient({ network: jungle4 }); + const actor = "forcedev1234"; const balance = await getBalance({ client, actor }); expect(balance).toBeDefined(); expect(balance.toString()).toBeDefined(); @@ -15,8 +14,8 @@ describe("getBalance", async () => { }); test("getBalance() should throw Error retrieving balance from unknown user.", async () => { - const client = createClient({ network: eos }); - const actor = Name.from("cryptonode99"); + const client = await createClient({ network: eos }); + const actor = "cryptonode99"; expect(async () => await getBalance({ client, actor })).toThrowError(); }); }); diff --git a/src/actions/token/getBalance.ts b/src/actions/token/getBalance.ts index 38dafafe..8ee90fab 100644 --- a/src/actions/token/getBalance.ts +++ b/src/actions/token/getBalance.ts @@ -1,24 +1,11 @@ -import type { Asset, Name } from "@wharfkit/session"; +import type { Asset, NameType } from "@wharfkit/session"; import type { Client } from "../../exports"; export type GetBalanceArgs = { client: Client; - actor: Name; + actor: NameType; }; -/** - * Get the balance of a user - * @param {{ client: Client, actor: Name}} Effect SDK client and the actor to get the balance for. - * @returns {Promise} The balance of the user - * @throws {Error} if no balance is found - * - * @example - * const client = createClient({ network: eos }); - * const actor = Name.from("cryptonode42"); - * const balance = await getBalance({ client, actor }); - * console.log(balance.toString()); - * // => "100.0000 EFX" - */ export const getBalance = async ({ client, actor, diff --git a/src/actions/token/swap.test.ts b/src/actions/token/swap.test.ts index 1e00ed8b..1f9dc919 100644 --- a/src/actions/token/swap.test.ts +++ b/src/actions/token/swap.test.ts @@ -13,7 +13,7 @@ describe("Swap", async () => { test("swap() should throw an error when Session is not set on Client.", async () => { const swapArgs: SwapArgs = { - client: createClient({ network: jungle4 }), + client: await createClient({ network: jungle4 }), amount: 1, direction: "UsdtToEfx", }; @@ -25,7 +25,7 @@ describe("Swap", async () => { test("swap() should fail when amount is 0", async () => { const swapArgs: SwapArgs = { - client: await testClientSession({ testEnvNetwork: jungle4 }), + client: await testClientSession(), amount: 0, direction: "UsdtToEfx", }; diff --git a/src/actions/token/swap.ts b/src/actions/token/swap.ts index c45ecc53..10884db2 100644 --- a/src/actions/token/swap.ts +++ b/src/actions/token/swap.ts @@ -1,8 +1,8 @@ import { type AnyAction, Asset, - type Name, type PermissionLevelType, + type NameType, } from "@wharfkit/antelope"; import type { Client } from "../../client"; import { DefiBoxPairEnum } from "./getDefiBoxPair"; @@ -16,7 +16,7 @@ export const swapDirection = { export const buildSwapAction = ( direction: string, - actor: Name, + actor: NameType, authorization: PermissionLevelType[], amount: number, tokenContract: string, @@ -68,6 +68,7 @@ export type SwapArgs = { direction: "EfxToUsdt" | "UsdtToEfx"; }; +// TODO: Add throw error if balance too low export const swap = async ({ client, amount, direction }: SwapArgs) => { try { if (!client.session) { diff --git a/src/actions/token/token.test.ts b/src/actions/token/token.test.ts index 7ae96c84..d0db7e59 100644 --- a/src/actions/token/token.test.ts +++ b/src/actions/token/token.test.ts @@ -4,12 +4,10 @@ import { getBalance } from "./getBalance"; import { swap, type SwapArgs } from "./swap"; import { createClient } from "../../client"; import { eos, jungle4 } from "../../exports"; -import { Name } from "@wharfkit/antelope"; import { testClientSession } from "../../../test/src/utils"; describe("getPrice", async () => { test("getPrice() should retrieve price on mainnet", async () => { - const client = createClient({ network: eos }); const price = await getPrice(); expect(price).toBeDefined(); expect(price).toBeNumber(); @@ -18,8 +16,8 @@ describe("getPrice", async () => { describe("getBalance", async () => { test("getBalance() should retrieve balance from user on mainnet", async () => { - const client = createClient({ network: jungle4 }); - const actor = Name.from("forcedev1234"); + const client = await createClient({ network: jungle4 }); + const actor = "forcedev1234"; const balance = await getBalance({ client, actor }); expect(balance).toBeDefined(); expect(balance.toString()).toBeDefined(); @@ -27,8 +25,8 @@ describe("getBalance", async () => { }); test("getBalance() should throw Error retrieving balance from unknown user.", async () => { - const client = createClient({ network: eos }); - const actor = Name.from("cryptonode99"); + const client = await createClient({ network: eos }); + const actor = "cryptonode99"; expect(async () => await getBalance({ client, actor })).toThrowError(); }); }); @@ -42,7 +40,7 @@ describe("Swap", async () => { test("swap() should throw an error when Session is not set on Client.", async () => { const swapArgs: SwapArgs = { - client: createClient({ network: jungle4 }), + client: await createClient({ network: jungle4 }), amount: 1, direction: "UsdtToEfx", }; @@ -54,7 +52,7 @@ describe("Swap", async () => { test("swap() should fail when amount is 0", async () => { const swapArgs: SwapArgs = { - client: await testClientSession({ testEnvNetwork: jungle4 }), + client: await testClientSession(), amount: 0, direction: "UsdtToEfx", }; diff --git a/src/actions/vaccount/claim.test.ts b/src/actions/vaccount/claim.test.ts new file mode 100644 index 00000000..e9b970d8 --- /dev/null +++ b/src/actions/vaccount/claim.test.ts @@ -0,0 +1,17 @@ +import { expect, test, describe } from "bun:test"; +import { testClientSession } from "../../../test/src/utils"; +import { claim } from "../../exports"; + +describe("Claim", async () => { + test.todo("Should throw when no payment is pending", async () => { + const client = await testClientSession(); + const response = await claim({ client }); + // expect(async () => await claim({ client })).toThrow(); + expect(response).toBeDefined(); + }); + + test.todo("Should claim pending payments", async () => { + // TODO: Should claim pending payments + // Figure out flow to test this + }); +}); diff --git a/src/actions/vaccount/claim.ts b/src/actions/vaccount/claim.ts index 2ae99049..60677c28 100644 --- a/src/actions/vaccount/claim.ts +++ b/src/actions/vaccount/claim.ts @@ -1,4 +1,4 @@ -import type { AnyAction, Name } from "@wharfkit/antelope"; +import type { AnyAction, NameType } from "@wharfkit/antelope"; import type { Client } from "../../client"; import { VAccountError } from "../../errors"; import { useEFXContracts } from "../../utils/state"; @@ -43,7 +43,7 @@ export const claim = async ({ client }: ClaimArgs) => { export type ClaimActionsArgs = { payments: Payment[]; tasks: string; - authorization: { actor: Name; permission: Name }[]; + authorization: { actor: NameType; permission: NameType }[]; }; export const claimActions = ({ diff --git a/src/actions/vaccount/createAccount.test.ts b/src/actions/vaccount/createAccount.test.ts index 3ef79d4b..c74bc29e 100644 --- a/src/actions/vaccount/createAccount.test.ts +++ b/src/actions/vaccount/createAccount.test.ts @@ -1,18 +1,18 @@ import { Name } from "@wharfkit/antelope"; -import { expect, test, describe, mock } from "bun:test"; +import { expect, test, describe } from "bun:test"; import { createClient } from "../../client"; import { createVAccount } from "./createAccount"; import { jungle4 } from "../../exports"; -import { destructureEnv, testClientSession } from "../../../test/src/utils.js"; +import { testClientSession } from "../../../test/src/utils.js"; describe("Create Virtual account", () => { - const testEnvNetwork = jungle4; + const network = jungle4; test.skip("createVAccount() should return a TransactResult", async () => { - const client = await testClientSession({ testEnvNetwork }); + const client = await testClientSession(); const account = Name.from("efxforce1112"); const result = await createVAccount({ client, account }); expect(result).toBeDefined(); @@ -20,7 +20,7 @@ describe("Create Virtual account", () => { test("createVAccount() should throw Error when no Session is found", async () => { expect(async () => { - const client = createClient({ network: testEnvNetwork }); + const client = await createClient({ network: network }); const account = Name.from("efxforce1112"); await createVAccount({ client, account }); }).toThrowError(); diff --git a/src/actions/vaccount/createAccount.ts b/src/actions/vaccount/createAccount.ts index d9a172d2..1d2f2889 100644 --- a/src/actions/vaccount/createAccount.ts +++ b/src/actions/vaccount/createAccount.ts @@ -1,4 +1,4 @@ -import type { Name, TransactResult, Session } from "@wharfkit/session"; +import type { TransactResult, Session, NameType } from "@wharfkit/session"; import type { Client } from "../../client"; import { ExtendedSymbol } from "../../utils/structs"; import { VAddress } from "../../utils/variants"; @@ -6,33 +6,9 @@ import { VAddress } from "../../utils/variants"; export type CreateVAccountArgs = { client: Client; session?: Session; - account?: Name; + account?: NameType; }; -/** - * Creates a virtual Effect account - * Client must be initialized - * Session is optional if the client has a session already - * Account is optional, can be initialized with: - * - * ```ts - * import { Name } from "@wharfkit/session"; - * const account: Name = Name.from("accountname"); - * ``` - * The account name must be a valid EOS account name. - * If no account is provided, the current session actor will be used. - * - * @param {CreateVAccountArgs} { client, session, account } - Provide the client, session, and account name. - * @returns {TransactResult = The result of the the transaction.} - * - * @example - * ```ts - * import { createVAccount } from "@effectai/effect-js"; - * import { Name } from "@wharfkit/session"; - * const account: Name = Name.from("accountname"); - * const result = await createVAccount({ client, account }); - * ``` - */ export const createVAccount = async ({ client, session, @@ -44,8 +20,8 @@ export const createVAccount = async ({ throw new Error("No session provided"); } - // If no account is provided, use the current session actor - const acc: Name = account ?? sessionToUse.actor; + // TODO: If no account is provided, use the current session actor. Not implemented yet + const acc: NameType = account ?? sessionToUse.actor; const { actor } = sessionToUse; const { contracts, token } = client.network.config.efx; diff --git a/src/actions/vaccount/deposit.test.ts b/src/actions/vaccount/deposit.test.ts index f6d2fe55..688d77b3 100644 --- a/src/actions/vaccount/deposit.test.ts +++ b/src/actions/vaccount/deposit.test.ts @@ -1,23 +1,20 @@ import { describe, test, expect } from "bun:test"; import { deposit } from "./deposit"; -import { eos, jungle4 } from "../../exports"; -import { getOrCreateVAccount } from "./getOrCreate"; -import { Name } from "@wharfkit/antelope"; import { testClientSession, destructureEnv } from "../../../test/src/utils"; +import { getVAccounts } from "./getAccounts"; describe("deposit", async () => { - test.todo("Should throw an error when Session is not set on Client.", () => { - // TODO: implement test - }); + test.todo( + "Should throw an error when Session is not set on Client.", + () => {}, + ); test.skip("Check that deposit is functioning correctly", async () => { - const { network, actor } = destructureEnv(); - const client = await testClientSession({ testEnvNetwork: network }); - console.debug(client.network); - const acc = Name.from(actor); - const vAccount = await getOrCreateVAccount({ client, actor: acc }); - const vAccId = Number(vAccount.id); - const result = await deposit({ client, vAccountId: vAccId, amount: 0.1 }); - console.debug(result); + const { actor } = destructureEnv(); + const client = await testClientSession(); + const [vAccount] = await getVAccounts({ client, actor }); + const vAccountId = vAccount.id; + const result = await deposit({ client, vAccountId, amount: 0.1 }); + expect(result).toBeDefined(); }); }); diff --git a/src/actions/vaccount/getAccounts.test.ts b/src/actions/vaccount/getAccounts.test.ts index 75fa2eef..9a2010e8 100644 --- a/src/actions/vaccount/getAccounts.test.ts +++ b/src/actions/vaccount/getAccounts.test.ts @@ -1,14 +1,11 @@ import { expect, test, describe, beforeAll } from "bun:test"; -import type { VAccount } from "../../types/user"; import type { Client } from "../../client"; import { testClientSession } from "../../../test/src/utils"; - import { getVAccounts, getAccountById } from "./getAccounts"; -import { Name } from "@wharfkit/antelope"; -import { jungle4 } from "../../exports"; +import type { Account } from "../../exports"; describe("Get Virtual Accounts", () => { - const vaccExample: VAccount = { + const vaccExample: Account = { id: 0, nonce: 53, address: ["name", "efxforceacc1"], @@ -20,11 +17,11 @@ describe("Get Virtual Accounts", () => { let client: Client; beforeAll(async () => { - client = await testClientSession({ testEnvNetwork: jungle4 }); + client = await testClientSession(); }); test("getVAccounts() on testnet", async () => { - const actor = Name.from("efxforce1112"); + const actor = "efxforce1112"; const vaccs = await getVAccounts({ client, actor }); expect(vaccs).toBeDefined(); expect(vaccs).toBeArray(); diff --git a/src/actions/vaccount/getAccounts.ts b/src/actions/vaccount/getAccounts.ts index 3b2db2d0..5faa2823 100644 --- a/src/actions/vaccount/getAccounts.ts +++ b/src/actions/vaccount/getAccounts.ts @@ -1,4 +1,4 @@ -import type { Name, UInt64Type } from "@wharfkit/antelope"; +import { Name, type NameType, type UInt64Type } from "@wharfkit/antelope"; import type { Client } from "../../client"; import { NotFoundError } from "../../errors"; import { generateCheckSumForVAccount } from "../../utils/keys"; @@ -6,14 +6,9 @@ import type { Account } from "../../@generated/types/efxaccount11"; export type GetVAccountsArgs = { client: Client; - actor: Name; + actor: NameType; }; -/** - * Get all virtual accounts for a given account - * @param {GetVAccountsArgs} getVAccountargs - Object with sdk client and account name - * @returns {Promise} VAccount[] - Array of Effect Virtual Accounts - */ export const getVAccounts = async ({ client, actor, @@ -21,7 +16,7 @@ export const getVAccounts = async ({ const { provider, network } = client; const { contracts } = network.config.efx; - const keycs = generateCheckSumForVAccount(actor, contracts.token); + const keycs = generateCheckSumForVAccount(Name.from(actor), contracts.token); const response = await provider.v1.chain.get_table_rows({ code: contracts.vaccount, @@ -44,7 +39,7 @@ export type GetAccountByIdArgs = { export const getAccountById = async ({ client, accountId, -}: GetAccountByIdArgs) => { +}: GetAccountByIdArgs): Promise => { const { provider, network } = client; const { contracts } = network.config.efx; diff --git a/src/actions/vaccount/getAvatar.test.ts b/src/actions/vaccount/getAvatar.test.ts new file mode 100644 index 00000000..a70d02bf --- /dev/null +++ b/src/actions/vaccount/getAvatar.test.ts @@ -0,0 +1,17 @@ +import { expect, test, describe } from "bun:test"; +import { createClient } from "../../client"; +import { getAvatar, jungle4 as network } from "../../exports"; + +describe("getAvatar", async () => { + test.todo("Should retrieve avatar for user", async () => { + const client = await createClient({ network }); + const account = "cryptonode42"; + const response = await getAvatar({ client, account }); + expect(response).toBeDefined(); + }); + + test.todo("Should claim pending payments", async () => { + // TODO: Should claim pending payments + // Figure out flow to test this + }); +}); diff --git a/src/actions/vaccount/getAvatar.ts b/src/actions/vaccount/getAvatar.ts index c7cda088..5f7715a0 100644 --- a/src/actions/vaccount/getAvatar.ts +++ b/src/actions/vaccount/getAvatar.ts @@ -1,15 +1,21 @@ -import type { Client } from "../../client"; import { getAsset } from "../atomic/getAsset"; -import { getAvatar as getDaoAvatar } from "../dao/getAvatar"; +import { + getAvatar as getDaoAvatar, + type GetAvatarArgs, +} from "../dao/getAvatar"; -export const getAvatar = async (client: Client, account: string) => { +// TODO: This function is failing, but it is not mission critical for the app to work. +export const getAvatar = async ({ client, account }: GetAvatarArgs) => { const defaultImg = "QmZQiEWsaTNpANMv9orwDvuGyMRkY5nQNazSB1KkW4pM6t"; const defaultVid = "QmZQiEWsaTNpANMv9orwDvuGyMRkY5nQNazSB1KkW4pM6t"; - const daoAvatar = await getDaoAvatar({ client, account }); + + // This function is failing, let's comment it out for now. + // const daoAvatar = await getDaoAvatar({ client, account }); const asset = await getAsset({ client, account, - assetId: daoAvatar.asset_id, + assetId: "2199025109172", + // assetId: daoAvatar.asset_id, }); return { ...asset, diff --git a/src/actions/vaccount/getOrCreate.test.ts b/src/actions/vaccount/getOrCreate.test.ts new file mode 100644 index 00000000..403eedca --- /dev/null +++ b/src/actions/vaccount/getOrCreate.test.ts @@ -0,0 +1,29 @@ +import { expect, test, describe } from "bun:test"; +import { destructureEnv, testClientSession } from "../../../test/src/utils"; +import type { Account } from "../../exports"; +import { getOrCreateVAccount } from "./getOrCreate"; + +describe("GetOrCreate", async () => { + const vaccExample: Account = { + id: 0, + nonce: 53, + address: ["name", "efxforceacc1"], + balance: { + quantity: "3525.0000 EFX", + contract: "effecttokens", + }, + }; + + test("Should get account", async () => { + const client = await testClientSession(); + const { actor } = destructureEnv(); + const result = await getOrCreateVAccount({ client, actor }); + expect(result).toBeDefined(); + expect(result).toContainKeys(Object.keys(vaccExample)); + }); + + test.todo("Should create new account", async () => { + // TODO: Should create new account + // Figure out flow to test this + }); +}); diff --git a/src/actions/vaccount/getOrCreate.ts b/src/actions/vaccount/getOrCreate.ts index 1075c89a..31033a02 100644 --- a/src/actions/vaccount/getOrCreate.ts +++ b/src/actions/vaccount/getOrCreate.ts @@ -1,6 +1,11 @@ -import type { Name } from "@wharfkit/antelope"; +import type { NameType } from "@wharfkit/antelope"; import type { Session } from "@wharfkit/session"; -import { type Client, createVAccount, getVAccounts } from "../../exports"; +import { + type Client, + createVAccount, + getVAccounts, + type Account, +} from "../../exports"; export const getOrCreateVAccount = async ({ client, @@ -8,9 +13,9 @@ export const getOrCreateVAccount = async ({ session, }: { client: Client; - actor: Name; + actor: NameType; session?: Session; -}) => { +}): Promise => { try { let [account] = await getVAccounts({ client, actor }); diff --git a/src/actions/vaccount/getPendingPayments.test.ts b/src/actions/vaccount/getPendingPayments.test.ts new file mode 100644 index 00000000..2d04a7ed --- /dev/null +++ b/src/actions/vaccount/getPendingPayments.test.ts @@ -0,0 +1,23 @@ +import { describe, expect, test } from "bun:test"; +import { testClientSession, destructureEnv } from "../../../test/src/utils"; +import { getPendingPayments } from "./getPendingPayments"; +import { getVAccounts } from "./getAccounts"; + +describe("getPendingPayments", () => { + const pendingPaymentsExample = { + pendingPayments: [], + claimablePayments: [], + totalEfxPending: 0, + totalEfxClaimable: 0, + }; + + test("getPendingPayments() returns pendingPayments", async () => { + const { actor } = destructureEnv(); + const client = await testClientSession(); + const [vaccount] = await getVAccounts({ client, actor }); + const vAccountId = vaccount.id; + const pendingPayments = await getPendingPayments({ client, vAccountId }); + expect(pendingPayments).toBeDefined(); + expect(pendingPayments).toMatchObject(pendingPaymentsExample); + }); +}); diff --git a/src/actions/vaccount/payout.test.ts b/src/actions/vaccount/payout.test.ts new file mode 100644 index 00000000..c93369b3 --- /dev/null +++ b/src/actions/vaccount/payout.test.ts @@ -0,0 +1,18 @@ +import { expect, test, describe } from "bun:test"; +import { destructureEnv, testClientSession } from "../../../test/src/utils"; +import { payout } from "../../exports"; + +describe("PayOut", async () => { + test("Should fail payout when there is no pending payout", async () => { + const { actor } = destructureEnv(); + const client = await testClientSession(); + expect(async () => await payout({ client, actor })).toThrowError( + "No payouts currently claimable.", + ); + }); + + test.todo("Should payout pending payments", async () => { + // TODO: Should payout pending payments + // Figure out flow to test this + }); +}); diff --git a/src/actions/vaccount/payout.ts b/src/actions/vaccount/payout.ts index 432b6d87..d9fd5704 100644 --- a/src/actions/vaccount/payout.ts +++ b/src/actions/vaccount/payout.ts @@ -1,4 +1,4 @@ -import { type AnyAction, ExtendedAsset, type Name } from "@wharfkit/antelope"; +import { type AnyAction, ExtendedAsset, type NameType } from "@wharfkit/antelope"; import type { Client } from "../../client"; import { VAccountError } from "../../errors"; import { useEFXContracts } from "../../utils/state"; @@ -9,7 +9,7 @@ import { withdrawAction } from "./withdraw"; /* claim & withdraw EFX to VAccount */ export type PayoutArgs = { client: Client; - actor: Name; + actor: NameType; }; export const payout = async ({ client, actor }: PayoutArgs) => { diff --git a/src/actions/vaccount/transfer.test.ts b/src/actions/vaccount/transfer.test.ts new file mode 100644 index 00000000..45691a74 --- /dev/null +++ b/src/actions/vaccount/transfer.test.ts @@ -0,0 +1,60 @@ +import { describe, expect, test, beforeAll } from "bun:test"; +import { testClientSession, destructureEnv } from "../../../test/src/utils"; +import { vTransfer } from "./transfer"; +import { getVAccounts, type Client } from "../../exports"; + +describe("vTransfer", () => { + const { actor } = destructureEnv(); + const receiver = "vibrantcacti"; + let client: Client; + const from_id = 1; + const to_id = 2; + const quantity = 0.0001; + + beforeAll(async () => { + client = await testClientSession(); + }); + + test("throws an error if session is not set", async () => { + expect(async () => { + await vTransfer({ client, from_id, to_id, quantity }); + }).toThrow(); + }); + + test.skip("Should return txResult, when sending 0.0001 EFX", async () => { + const [vAccount] = await getVAccounts({ client, actor }); + const preBalanceVAccount = Number(vAccount.balance.quantity); + + const [vAccountReceiver] = await getVAccounts({ + client, + actor: receiver, + }); + const preBalanceReceiver = Number(vAccountReceiver.balance.quantity); + + const result = await vTransfer({ + client, + from_id: vAccount.id, + to_id: vAccountReceiver.id, + quantity, + }); + + expect(result).toBeDefined(); + + const [postVAccount] = await getVAccounts({ + client, + actor, + }); + + const [postVAccountReceiver] = await getVAccounts({ + client, + actor: receiver, + }); + + const postbalanceReceiver = Number(postVAccountReceiver.balance.quantity); + const postbalance = Number(postVAccount.balance.quantity); + + // Make sure the balance is updated + expect(postbalance).toBe(preBalanceVAccount - quantity); + expect(postbalanceReceiver).toBe(preBalanceReceiver + quantity); + }); +}); diff --git a/src/actions/vaccount/transfer.ts b/src/actions/vaccount/transfer.ts index e27d7866..f03c720e 100644 --- a/src/actions/vaccount/transfer.ts +++ b/src/actions/vaccount/transfer.ts @@ -1,7 +1,9 @@ -import type { AnyAction } from "@wharfkit/antelope"; +import { Asset, type AnyAction } from "@wharfkit/antelope"; import type { Client } from "../../client"; import { SessionNotFoundError } from "../../errors"; import { useEFXContracts } from "../../utils/state"; +import type { TransactResult } from "@wharfkit/session"; +import { getVAccounts } from "./getAccounts"; export type vTransferActionArgs = { client: Client; @@ -31,7 +33,7 @@ export const vTransferAction = ({ from_id, to_id, quantity: { - quantity: quantity, + quantity: Asset.from(quantity, "4,EFX"), contract: token, }, memo: "", @@ -44,7 +46,7 @@ export const vTransferAction = ({ export type vTransferArgs = { client: Client; - from_id: number; + from_id?: number; // from_id is optional, if sesion is connected, sending from actor is possible. to_id: number; quantity: number; }; @@ -54,16 +56,18 @@ export const vTransfer = async ({ from_id, to_id, quantity, -}: vTransferArgs) => { +}: vTransferArgs): Promise => { if (!client.session) { throw new SessionNotFoundError("Session is required for this method."); } - const { transact } = client.session; + const { transact, actor } = client.session; + + const [vaccount] = await getVAccounts({ client, actor }); const transferAction = vTransferAction({ client, to_id, - from_id, + from_id: from_id ?? vaccount.id, quantity, }); diff --git a/src/actions/vaccount/withdraw.test.ts b/src/actions/vaccount/withdraw.test.ts new file mode 100644 index 00000000..cd1160e7 --- /dev/null +++ b/src/actions/vaccount/withdraw.test.ts @@ -0,0 +1,22 @@ +import { expect, test, describe } from "bun:test"; +import { testClientSession } from "../../../test/src/utils"; +import { withdraw } from "../../exports"; +import type { ExtendedAssetType } from "@wharfkit/antelope"; + +describe("withdraw", async () => { + test.skip("Should withdraw vaccount EFX to wallet.", async () => { + const client = await testClientSession(); + const quantity: ExtendedAssetType = { + quantity: "0.0001 EFX", + contract: client.network.config.efx.contracts.token, + }; + const result = await withdraw({ client, quantity }); + console.log(result); + expect(result).toBeDefined(); + }); + + test.todo("Should fail when no EFX is in vAccount", async () => { + // TODO: Should fail when no EFX is in the vAccount + // Figure out flow to test this + }); +}); diff --git a/src/actions/vaccount/withdraw.ts b/src/actions/vaccount/withdraw.ts index ae445334..812c2902 100644 --- a/src/actions/vaccount/withdraw.ts +++ b/src/actions/vaccount/withdraw.ts @@ -1,9 +1,15 @@ -import type { AnyAction, ExtendedAsset, Name } from "@wharfkit/antelope"; +import { + Asset, + ExtendedAsset, + type AnyAction, + type ExtendedAssetType, + type NameType, +} from "@wharfkit/antelope"; import type { Client } from "../../exports"; export type WithdrawArgs = { client: Client; - quantity: ExtendedAsset; + quantity: number; }; export const withdraw = async ({ client, quantity }: WithdrawArgs) => { @@ -13,11 +19,15 @@ export const withdraw = async ({ client, quantity }: WithdrawArgs) => { const { transact, actor, authorization } = client.session; const { contracts } = client.network.config.efx; + const quantityAsset = ExtendedAsset.from({ + quantity: Asset.from(quantity, "EFX"), + contract: contracts.token, + }); const action = withdrawAction({ from_id: client.session.vAccount.id, to_account: actor, - quantity, + quantity: quantityAsset, account: contracts.vaccount, authorization, memo: "", @@ -28,10 +38,10 @@ export const withdraw = async ({ client, quantity }: WithdrawArgs) => { export type WithdrawActionArgs = { from_id: number; - to_account: Name; - quantity: ExtendedAsset; + to_account: NameType; + quantity: ExtendedAssetType; account: string; - authorization: { actor: Name; permission: Name }[]; + authorization: { actor: NameType; permission: NameType }[]; memo: string; }; diff --git a/src/client.test.ts b/src/client.test.ts index 4ec654a1..d6b196ea 100644 --- a/src/client.test.ts +++ b/src/client.test.ts @@ -6,30 +6,22 @@ import { Session } from "@wharfkit/session"; describe("Client", async () => { test("Create client with Session", async () => { - const { network, permission, actor, privateKey } = destructureEnv(); + const { network: chain, permission, actor, privateKey } = destructureEnv(); // Create wallet with privatekey const walletPlugin = new WalletPluginPrivateKey(privateKey); // Set up session with wallet - const session = new Session({ - actor, - permission, - walletPlugin, - chain: { - id: network.id, - url: network.url, - }, - }); + const session = new Session({ actor, permission, walletPlugin, chain }); - const client = createClient({ session }); + const client = await createClient({ session }); expect(client.session).toBeDefined(); - expect(client.network.id).toBe(network.id); + expect(client.network.id).toBe(chain.id); }); test("Create client with Network", async () => { const { network } = destructureEnv(); - const client = createClient({ network }); + const client = await createClient({ network }); expect(client.session).toBeDefined(); }); }); diff --git a/src/client.ts b/src/client.ts index 6796cca3..fdb98e0e 100644 --- a/src/client.ts +++ b/src/client.ts @@ -88,7 +88,7 @@ export type CreateClientArgs = { options?: ClientOpts; } & ({ network: Network } | { session: Session }); -export const createClient = ({ +export const createClient = async ({ network, session, options = {}, @@ -99,6 +99,7 @@ export const createClient = ({ ); } + // TODO: We should also check that network and session.network are the same if (session) { // if session is given here, retrieve the network from session @@ -114,7 +115,7 @@ export const createClient = ({ const client = new Client(chain, options); // automatically set the session whenever the session is provided - client.setSession(session); + await client.setSession(session); return client; } diff --git a/src/constants/config.ts b/src/constants/config.ts index 9bc87997..6f1836ef 100644 --- a/src/constants/config.ts +++ b/src/constants/config.ts @@ -1,9 +1,4 @@ -import type { - AtomicConfig, - EfxConfig, - IpfsConfig, - RelayerConfig, -} from "../types/network"; +import type { AtomicConfig, IpfsConfig, RelayerConfig } from "../types/network"; export const ipfsConfig: IpfsConfig = { ipfsEndpoint: "https://ipfs.effect.ai", diff --git a/src/exports/index.ts b/src/exports/index.ts index 33020246..7e001d7f 100644 --- a/src/exports/index.ts +++ b/src/exports/index.ts @@ -11,7 +11,7 @@ export { export { getSchema, type getSchemaArgs } from "./../actions/atomic/getSchema"; -export { getAvatar, type GetAvatarArgs } from "./../actions/dao/getAvatar"; +export { type GetAvatarArgs } from "./../actions/dao/getAvatar"; export { getDaoSettings, type GetDaoSettingsArgs, @@ -107,7 +107,9 @@ export { export { getPrice } from "./../actions/token/getPrice"; export { getBalance, type GetBalanceArgs } from "./../actions/token/getBalance"; -export { swap, swapDirection } from "./../actions/token/swap"; +export { swap, swapDirection, type SwapArgs } from "./../actions/token/swap"; + +export { getAvatar } from "./../actions/vaccount/getAvatar"; export { getVAccounts, @@ -179,6 +181,11 @@ export type { GetTableRowsResponse } from "./types"; export { Template } from "./template"; -export { Session, Name } from "@wharfkit/session"; +export { + Session, + Name, + type NameType, + type ExtendedAssetType, +} from "@wharfkit/session"; export { version } from "./version"; diff --git a/src/session.ts b/src/session.ts index 8dc65c13..ec42497f 100644 --- a/src/session.ts +++ b/src/session.ts @@ -1,5 +1,5 @@ import type { - Name, + NameType, PermissionLevelType, Session, TransactArgs, @@ -10,10 +10,10 @@ import type { Account } from "./@generated/types/efxaccount11"; export class EffectSession { public readonly wharfKitSession: Session; - public readonly actor: Name; - public readonly permission: Name; + public readonly actor: NameType; + public readonly permission: NameType; public readonly permissionLevel: PermissionLevelType; - public readonly authorization: { actor: Name; permission: Name }[]; + public readonly authorization: { actor: NameType; permission: NameType }[]; private _vAccount: Account | null; diff --git a/src/utils/keys.ts b/src/utils/keys.ts index ffbdc572..675327c4 100644 --- a/src/utils/keys.ts +++ b/src/utils/keys.ts @@ -2,6 +2,7 @@ import { ABIEncoder, Checksum256, Name, + type NameType, UInt32, UInt64, } from "@wharfkit/antelope"; @@ -21,12 +22,12 @@ export function createCompositeU64Key(lowerId: number, upperId: number) { } export const generateCheckSumForVAccount = ( - actor: Name, + actor: NameType, tokenContract: string, ): Checksum256 => { const enc = new ABIEncoder(32); Name.from(tokenContract).toABI(enc); - const vaddr = VAddress.from(Name.from(actor.toString())); + const vaddr = VAddress.from(actor); enc.writeByte(vaddr.variantIdx); vaddr.value.toABI(enc); diff --git a/test/src/utils.ts b/test/src/utils.ts index 19da8465..95e48303 100644 --- a/test/src/utils.ts +++ b/test/src/utils.ts @@ -1,80 +1,60 @@ import { - PrivateKey, - type PrivateKeyType, - Session, - PermissionLevel, + PrivateKey, + type PrivateKeyType, + Session, } from "@wharfkit/session"; import { WalletPluginPrivateKey } from "@wharfkit/wallet-plugin-privatekey"; -import { jungle4, eos } from "../../src/exports"; +import { jungle4, } from "../../src/exports"; import { createClient } from "../../src/client"; import type { Client } from "../../src/client"; import type { Network } from "../../src/types/network"; declare module "bun" { - interface Env { - TESTNET_PERMISSION: string; - TESTNET_NETWORK_NAME: string; - TESTNET_ACTOR: string; - TESTNET_PRIVATE_KEY: string; - MAINNET_PERMISSION: string; - MAINNET_NETWORK_NAME: string; - MAINNET_ACTOR: string; - MAINNET_PRIVATE_KEY: string; - } + interface Env { + TESTNET_PERMISSION: string; + TESTNET_NETWORK_NAME: string; + TESTNET_ACTOR: string; + TESTNET_PRIVATE_KEY: string; + MAINNET_PERMISSION: string; + MAINNET_NETWORK_NAME: string; + MAINNET_ACTOR: string; + MAINNET_PRIVATE_KEY: string; + } } export interface testEnv { - network: Network; - networkName: string; - permission: string; - actor: string; - privateKey: PrivateKeyType; + network: Network; + networkName: string; + permission: string; + actor: string; + privateKey: PrivateKeyType; } export const destructureEnv = () => { - return { - network: jungle4, - networkName: process.env.NETWORK_NAME, - permission: process.env.PERMISSION!, - actor: process.env.ACTOR!, - privateKey: PrivateKey.from(process.env.PRIVATE_KEY!), - }; + return { + network: jungle4, + networkName: process.env.TESTNET_NETWORK_NAME, + permission: process.env.TESTNET_PERMISSION!, + actor: process.env.TESTNET_ACTOR!, + privateKey: PrivateKey.from(process.env.TESTNET_PRIVATE_KEY!), + }; }; -export const testClientSession = async ({ - testEnvNetwork, -}: { testEnvNetwork: Network }): Promise => { - // Retrieve parameters for session. - const { network, permission, actor, privateKey } = destructureEnv(); +export const testClientSession = async (): Promise => { + // Retrieve parameters for session. + const { network: chain, permission, actor, privateKey } = destructureEnv(); - if (!privateKey) { - throw new Error("Private key not found"); - } + if (!privateKey) { + throw new Error("Private key not found"); + } - const { url, id } = network; + // Setup wallet plugin with private key + const walletPlugin = new WalletPluginPrivateKey(privateKey); - // Create client - const client = createClient({ network }); + const session = new Session({ actor, permission, walletPlugin, chain }); - // Set up wallet with privatekey - const pk: PrivateKeyType = PrivateKey.fromString( - privateKey.toString(), - false, - ); + // Create client + const client = await createClient({ session }); - const walletPlugin = new WalletPluginPrivateKey(pk); - - // Set up session with wallet and chain - const session = new Session({ - actor, - permission, - walletPlugin, - chain: { id, url }, - permissionLevel: PermissionLevel.from(`${actor}@${permission}`), - }); - - // Connect session to client - await client.setSession(session); - - return client; + return client; };