Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,16 +355,16 @@ e.g.: `'[{"id":"cpu","amount":3},{"id":"ram","amount":16772672536},{"id":"disk",
**Create Access List:**

- **Positional:**
`npm run cli createAccessList "My Access List" "MAL" false "0xUser1,0xUser2"`
`npm run cli createAccessList "My Access List" "MAL" "0xUser1,0xUser2" false`

- **Named Options:**
`npm run cli createAccessList --name "My Access List" --symbol "MAL" --transferable false --users "0xUser1,0xUser2"`
`npm run cli createAccessList --name "My Access List" --symbol "MAL" --initial-users "0xUser1,0xUser2" --transferable false`

- Arguments:
- `name`: Name for the access list
- `symbol`: Symbol for the access list
- `transferable`: Whether tokens are transferable (true/false)
- `initialUsers`: Comma-separated list of initial user addresses (optional)
- `transferable`: Whether tokens are transferable (true/false, optional, default: `false`)

---

Expand Down Expand Up @@ -490,8 +490,8 @@ e.g.: `'[{"id":"cpu","amount":3},{"id":"ram","amount":16772672536},{"id":"disk",
- **createAccessList:**
`-n, --name <name>`
`-s, --symbol <symbol>`
`-t, --transferable [transferable]` (Default: `false`)
`-u, --users [initialUsers]` (Default: `''`)
`-u, --initial-users [initialUsers]` (Default: `''`)
`-t, --transferable [transferable]` (Default: `false`)

- **addToAccessList:**
`-a, --address <accessListAddress>`
Expand Down
26 changes: 13 additions & 13 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
denyDialMultiaddr: () => false,
},
},
} as any);

Check warning on line 72 in src/cli.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
console.log(
chalk.cyan("libp2p node started. Waiting for peer connections...")
);
Expand All @@ -83,7 +83,7 @@
const maxWait = 20_000;
const interval = 500;
let waited = 0;
const libp2p = (ProviderInstance as any).p2pProvider?.libp2pNode;

Check warning on line 86 in src/cli.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
const isTargetConnected = () =>
(libp2p?.getPeers() ?? []).some(
(p: { toString(): string }) => p.toString() === targetPeerId
Expand Down Expand Up @@ -680,36 +680,36 @@
.description("Create a new access list contract")
.argument("<name>", "Name for the access list")
.argument("<symbol>", "Symbol for the access list")
.argument(
"[initialUsers]",
"Comma-separated list of initial user addresses",
""
)
.argument(
"[transferable]",
"Whether tokens are transferable (true/false)",
"false"
)
.argument(
"[initialUsers]",
.option("-n, --name <name>", "Name for the access list")
.option("-s, --symbol <symbol>", "Symbol for the access list")
.option(
"-u, --initial-users [initialUsers]",
"Comma-separated list of initial user addresses",
""
)
.option("-n, --name <name>", "Name for the access list")
.option("-s, --symbol <symbol>", "Symbol for the access list")
.option(
"-t, --transferable [transferable]",
"Whether tokens are transferable (true/false)",
"false"
)
.option(
"-u, --users [initialUsers]",
"Comma-separated list of initial user addresses",
""
)
.action(async (name, symbol, transferable, initialUsers, options) => {
.action(async (name, symbol, initialUsers, transferable, options) => {
const { signer, chainId } = await initializeSigner();
const commands = new Commands(signer, chainId);
await commands.createAccessList([
options.name || name,
options.symbol || symbol,
options.transferable || transferable,
options.users || initialUsers,
options.initialUsers || initialUsers,
]);
});

Expand Down Expand Up @@ -818,8 +818,8 @@

program
.command("createBucket")
.description("Create a new persistent-storage bucket gated by a single access list (chain inferred from RPC)")
.argument("<accessListAddress>", "Access list contract address (0x…)")
.description("Create a new persistent-storage bucket. Pass an access list to gate it; omit for owner-only access (chain inferred from RPC)")
.argument("[accessListAddress]", "Access list contract address (0x…); omit for owner-only access")
.action(async (accessListAddress) => {
const { signer, chainId } = await initializeSigner();
const commands = new Commands(signer, chainId);
Expand Down
18 changes: 9 additions & 9 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1707,7 +1707,7 @@
)
);
removedCount++;
} catch (e: any) {

Check warning on line 1710 in src/commands.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
console.log(
chalk.yellow(
`⚠ Could not remove token at index ${index} for user ${user}: ${e.message}`
Expand Down Expand Up @@ -1799,17 +1799,17 @@
public async createBucket(args: string[]): Promise<void> {
try {
const accessListAddress = args[1];
if (!accessListAddress) {
console.error(chalk.red("accessListAddress is required"));
return;
}
if (!/^0x[a-fA-F0-9]{40}$/.test(accessListAddress)) {
console.error(chalk.red(`Invalid access list address: ${accessListAddress}`));
return;
let accessLists: Array<{ [chainId: string]: string[] }> = [];

if (accessListAddress) {
if (!/^0x[a-fA-F0-9]{40}$/.test(accessListAddress)) {
console.error(chalk.red(`Invalid access list address: ${accessListAddress}`));
return;
}
const { chainId } = await this.signer.provider.getNetwork();
accessLists = [{ [String(chainId)]: [accessListAddress] }];
}

const { chainId } = await this.signer.provider.getNetwork();
const accessLists = [{ [String(chainId)]: [accessListAddress] }];
const result = await ProviderInstance.createPersistentStorageBucket(
this.oceanNodeUrl,
this.signer,
Expand Down
9 changes: 4 additions & 5 deletions test/accessList.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
describe("Ocean CLI Access List", function () {
this.timeout(120000);

let chainConfig: any;

Check warning on line 11 in test/accessList.test.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
let accessListAddress: string;
let owner: ethers.Wallet;
let testUser1: ethers.Wallet;
Expand All @@ -33,10 +33,9 @@
it("should create a new access list contract", async function () {
const name = "TestAccessList";
const symbol = "TAL";
const transferable = "false";

const output = await runCommand(
`npm run cli createAccessList ${name} ${symbol} ${transferable}`
`npm run cli createAccessList ${name} ${symbol}`
);

expect(output).to.include("Access list created successfully");
Expand All @@ -58,7 +57,7 @@
const initialUsers = `${testUser1.address},${testUser2.address}`;

const output = await runCommand(
`npm run cli createAccessList ${name} ${symbol} ${transferable} ${initialUsers}`
`npm run cli createAccessList ${name} ${symbol} ${initialUsers} ${transferable}`
);

expect(output).to.include("Access list created successfully");
Expand All @@ -70,7 +69,7 @@
try {
await runCommand(`npm run cli createAccessList`);
throw new Error("Should have thrown an error");
} catch (error: any) {

Check warning on line 72 in test/accessList.test.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
expect(error.stderr || error.message).to.satisfy((msg: string) =>
msg.includes("error: missing required argument") ||
msg.includes("Name and symbol are required")
Expand Down Expand Up @@ -238,7 +237,7 @@
describe("Edge Cases", function () {
it("should handle empty initial users list", async function () {
const output = await runCommand(
`npm run cli createAccessList EmptyList EL false ""`
`npm run cli createAccessList EmptyList EL "" false`
);

expect(output).to.include("Access list created successfully");
Expand All @@ -263,7 +262,7 @@
describe("E2E Workflow", function () {
it("should complete a full access list workflow", async function () {
const createOutput = await runCommand(
`npm run cli createAccessList WorkflowTest WT false`
`npm run cli createAccessList WorkflowTest WT`
);
expect(createOutput).to.include("Access list created successfully");

Expand Down
40 changes: 39 additions & 1 deletion test/storage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe("Ocean CLI Persistent Storage", function () {

it("should create an access list and add Alice and Bob", async function () {
const createOutput = await runCommand(
`npm run cli createAccessList StorageTestACL STACL false`
`npm run cli createAccessList StorageTestACL STACL`
);
expect(createOutput).to.include("Access list created successfully");
const addressMatch = createOutput.match(
Expand Down Expand Up @@ -122,4 +122,42 @@ describe("Ocean CLI Persistent Storage", function () {
);
expect(listOutput).to.not.include(fileName);
});

describe("Owner-only bucket (no ACL)", function () {
let ownerOnlyBucketId: string;

it("Alice should create a bucket without an access list", async function () {
const output = await runCommand(`npm run cli createBucket`);
expect(output).to.include("Bucket created.");
const idMatch = output.match(
/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/
);
if (!idMatch) {
throw new Error("Could not extract bucketId from output");
}
ownerOnlyBucketId = idMatch[0];
expect(output.toLowerCase()).to.include(alice.address.toLowerCase());
});

it("Alice (owner) should upload and list files in the no-ACL bucket", async function () {
const uploadOutput = await runCommand(
`npm run cli addFileToBucket ${ownerOnlyBucketId} ${tempFilePath}`
);
expect(uploadOutput).to.include(fileName);

const listOutput = await runCommand(
`npm run cli listFilesInBucket ${ownerOnlyBucketId}`
);
expect(listOutput).to.include(fileName);
expect(listOutput).to.not.match(/Error listing files/i);
});

it("Bob (not the owner) should not see Alice's files in the no-ACL bucket", async function () {
const bobOutput = await runCommandAs(
BOB_KEY,
`npm run cli listFilesInBucket ${ownerOnlyBucketId}`
);
expect(bobOutput).to.not.include(fileName);
});
});
});
Loading