Skip to content

Commit

Permalink
Merge pull request #43 from aptos-labs/support_multiple_contracts_2
Browse files Browse the repository at this point in the history
Support multiple contracts 2
  • Loading branch information
0xmaayan authored Dec 5, 2024
2 parents 6612a34 + b766edd commit 9754c05
Show file tree
Hide file tree
Showing 8 changed files with 660 additions and 25 deletions.
589 changes: 588 additions & 1 deletion examples/move-program/package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions examples/move-program/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"@aptos-labs/ts-sdk": "^1.30.0"
},
"devDependencies": {
"@aptos-labs/workspace": "file:../../workspace",
"chai": "^4.5.0"
Expand Down
2 changes: 1 addition & 1 deletion examples/ts-node-app/abis/todolist_abi.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const TODOLIST_ABI = {"address":"0x3933100e09d9dded0e68365c8870e481a4ee403d531bd299a4ef2053738ae6a3","name":"todolist","friends":[],"exposed_functions":[{"name":"complete_task","visibility":"public","is_entry":true,"is_view":false,"generic_type_params":[],"params":["&signer","u64"],"return":[]},{"name":"create_list","visibility":"public","is_entry":true,"is_view":false,"generic_type_params":[],"params":["&signer"],"return":[]},{"name":"create_task","visibility":"public","is_entry":true,"is_view":false,"generic_type_params":[],"params":["&signer","0x1::string::String"],"return":[]}],"structs":[{"name":"Task","is_native":false,"is_event":true,"abilities":["copy","drop","store"],"generic_type_params":[],"fields":[{"name":"task_id","type":"u64"},{"name":"address","type":"address"},{"name":"content","type":"0x1::string::String"},{"name":"completed","type":"bool"}]},{"name":"TodoList","is_native":false,"is_event":false,"abilities":["key"],"generic_type_params":[],"fields":[{"name":"tasks","type":"0x1::table::Table<u64, 0x3933100e09d9dded0e68365c8870e481a4ee403d531bd299a4ef2053738ae6a3::todolist::Task>"},{"name":"task_counter","type":"u64"}]}]} as const;
export const TODOLIST_ABI = {"address":"0x73be7292ae896a31b98c3b07ad439a0a746edce3e20094d2f239a64917798db9","name":"todolist","friends":[],"exposed_functions":[{"name":"complete_task","visibility":"public","is_entry":true,"is_view":false,"generic_type_params":[],"params":["&signer","u64"],"return":[]},{"name":"create_list","visibility":"public","is_entry":true,"is_view":false,"generic_type_params":[],"params":["&signer"],"return":[]},{"name":"create_task","visibility":"public","is_entry":true,"is_view":false,"generic_type_params":[],"params":["&signer","0x1::string::String"],"return":[]}],"structs":[{"name":"Task","is_native":false,"is_event":true,"abilities":["copy","drop","store"],"generic_type_params":[],"fields":[{"name":"task_id","type":"u64"},{"name":"address","type":"address"},{"name":"content","type":"0x1::string::String"},{"name":"completed","type":"bool"}]},{"name":"TodoList","is_native":false,"is_event":false,"abilities":["key"],"generic_type_params":[],"fields":[{"name":"tasks","type":"0x1::table::Table<u64, 0x73be7292ae896a31b98c3b07ad439a0a746edce3e20094d2f239a64917798db9::todolist::Task>"},{"name":"task_counter","type":"u64"}]}]} as const;
16 changes: 14 additions & 2 deletions workspace/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,16 @@ npm install --save-dev @thalalabs/surf
```

Surf uses the contract ABI to infer the types of the contract's functions and events.
To generate your contract ABI, you can use the `npx aptos-workspace gen-abi` command.
To generate your contract ABI, you can use the `npx aptos-workspace gen-abi` command and specify the names you used in the `named-addresses` for the Move binary along with the name of the address you want to generate the ABI for.

```bash
npx aptos-workspace gen-abi
# in your Move.toml
[addresses]
alice = "0x1"
bob = "0x2"

# in your terminal
npx aptos-workspace gen-abi --names alice,bob --name alice
```

This function will generate the ABI for your contracts and save it in the `abis` directory.
Expand All @@ -227,6 +233,12 @@ To run your Move unit tests, you can use the `npx aptos-workspace move-unit-tes`
npx aptos-workspace move-unit-test
```

By default, Workspace will look for the Move package under the folder specified in the `workspace.config` file. If your Move package is under a sub folder (e.g. `contract/MessageBoard` - for cases you have multiple move packages in your project), you can specify a `--package-path` flag.

```bash
npx aptos-workspace move-unit-test --package-path MessageBoard
```

### Using `pnpm` or `yarn`?

#### Using yarn?
Expand Down
18 changes: 15 additions & 3 deletions workspace/src/internal/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,29 @@ program
program
.command("move-unit-test")
.description("Run Move unit tests")
.action(async () => {
await moveUnitTestTask();
.option(
"--package-path <PATH>",
"The path to the Move package with a Move.toml file you want to test, Example: my-contract-folder-name"
)
.action(async (options) => {
await moveUnitTestTask(options);
});

program
.command("gen-abi")
.description("Generate the module ABI")
.option(
.requiredOption(
"--names <NAMES>",
"The names you use in the named-addresses for the move binary, Example: alice,bob"
)
.requiredOption(
"--name <NAME>",
"The name from the named-addresses to use to publish the package, Example: alice"
)
.option(
"--package-path <PATH>",
"The path to the Move package with a Move.toml file you want to generate the ABI for, Example: my-contract-folder-name"
)
.action(async (options) => {
/**
* NOTE: The only feasible way to generate the ABI is to publish the package to chain
Expand Down
2 changes: 1 addition & 1 deletion workspace/src/internal/rootHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const mochaHooks: RootHookObject = {
/**
* Spins up a new Aptos node and assigns it to the global `workspace` object.
*/
const createGlobalAptosClientInstance = async () => {
export const createGlobalAptosClientInstance = async () => {
workspace.testNode = await TestNode.spawn();
// inject aptos instance to the global `workspace` object.

Expand Down
30 changes: 18 additions & 12 deletions workspace/src/tasks/gen-abi.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,43 @@
import fs from "fs";
const cli = require("@aptos-labs/ts-sdk/dist/common/cli/index.js");
import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk";

import { publishMovePackageTask } from "./publishMovePackage";
import { generateTestAccount } from "../external";
import { generateTestAccount, workspace } from "../external";
import { createGlobalAptosClientInstance } from "../internal/rootHook";

export const genAbi = async (options: { names: string }) => {
const localNode = new cli.LocalNode();
export type GenAbiOptions = {
names: string;
name: string;
packagePath?: string;
};

export const genAbi = async (options: GenAbiOptions) => {
const { names, name, packagePath } = options;
console.log(`Generating ABI... hold on`);
// spin up a localnet
await localNode.run();
await createGlobalAptosClientInstance();
// create a random account
const publisher = await generateTestAccount();
// build the named addresses object with the random account address
const parsedNamedAddresses = buildAddressObject(
options.names,
names,
publisher.accountAddress.toString()
);
// publish the package to chain
const packageObjectAddress = await publishMovePackageTask({
publisher,
namedAddresses: parsedNamedAddresses,
addressName: Object.keys(parsedNamedAddresses)[0],
addressName: name,
packageFolderName: packagePath,
});
// fetch the abi from the node and generate in a local file
await fetchAbiFromNode(packageObjectAddress);
// stop the localnet
await localNode.stop();
await workspace.testNode.stop();
console.log(`ABI generated successfully in the abis/ folder`);
};

export const fetchAbiFromNode = async (objectAddress: string) => {
const aptosConfig = new AptosConfig({ network: Network.LOCAL });
const aptos = new Aptos(aptosConfig);
const modules = await aptos.getAccountModules({
const modules = await workspace.getAccountModules({
accountAddress: objectAddress,
});
modules.forEach((module) => {
Expand Down
25 changes: 20 additions & 5 deletions workspace/src/tasks/unit-test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
import path from "path";
import { Move } from "@aptos-labs/ts-sdk/dist/common/cli/index.js";
import fs from "fs";
import toml from "toml";
import { getUserConfigContractDir } from "../internal/utils/userConfig";
import {
getUserConfigContractDir,
getUserConfigVerbose,
} from "../internal/utils/userConfig";

export type MoveUnitTestOptions = {
packagePath?: string;
};

export const moveUnitTestTask = async (options: MoveUnitTestOptions) => {
const { packagePath } = options;

export const moveUnitTestTask = async () => {
// get the configured contract dir
const contractDir = getUserConfigContractDir();

const contractPackagePath = packagePath
? path.join(contractDir, packagePath)
: contractDir;

// read the Move.toml file
var str = fs.readFileSync(contractDir + "/Move.toml", "utf-8");
var str = fs.readFileSync(contractPackagePath + "/Move.toml", "utf-8");
// parse the Move.toml file and extract the named addresses
const namedAddresses = toml.parse(str).addresses;

Expand All @@ -18,8 +33,8 @@ export const moveUnitTestTask = async () => {
});

await new Move().test({
packageDirectoryPath: contractDir,
packageDirectoryPath: contractPackagePath,
namedAddresses,
showStdout: false,
showStdout: true,
});
};

0 comments on commit 9754c05

Please sign in to comment.