From a598974044e645e45fcba4324508d54773001f90 Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Tue, 5 May 2026 09:28:54 +0300 Subject: [PATCH 1/4] fix param order --- README.md | 10 +++++----- src/cli.ts | 22 +++++++++++----------- test/accessList.test.ts | 9 ++++----- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index b1af3e99..4b918499 100644 --- a/README.md +++ b/README.md @@ -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`) --- @@ -490,8 +490,8 @@ e.g.: `'[{"id":"cpu","amount":3},{"id":"ram","amount":16772672536},{"id":"disk", - **createAccessList:** `-n, --name ` `-s, --symbol ` - `-t, --transferable [transferable]` (Default: `false`) - `-u, --users [initialUsers]` (Default: `''`) + `-u, --initial-users [initialUsers]` (Default: `''`) + `-t, --transferable [transferable]` (Default: `false`) - **addToAccessList:** `-a, --address ` diff --git a/src/cli.ts b/src/cli.ts index f59eda1b..174083b4 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -680,36 +680,36 @@ export async function createCLI() { .description("Create a new access list contract") .argument("", "Name for the access list") .argument("", "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 for the access list") + .option("-s, --symbol ", "Symbol for the access list") + .option( + "-u, --initial-users [initialUsers]", "Comma-separated list of initial user addresses", "" ) - .option("-n, --name ", "Name for the access list") - .option("-s, --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, ]); }); diff --git a/test/accessList.test.ts b/test/accessList.test.ts index 39780d2e..72f776a8 100644 --- a/test/accessList.test.ts +++ b/test/accessList.test.ts @@ -33,10 +33,9 @@ describe("Ocean CLI Access List", function () { 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"); @@ -58,7 +57,7 @@ describe("Ocean CLI Access List", function () { 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"); @@ -238,7 +237,7 @@ describe("Ocean CLI Access List", function () { 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"); @@ -263,7 +262,7 @@ describe("Ocean CLI Access List", function () { 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"); From b54a0f0c48f059c372f790563b48d784af65cceb Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Tue, 5 May 2026 09:37:13 +0300 Subject: [PATCH 2/4] test fix --- test/storage.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/storage.test.ts b/test/storage.test.ts index f97a56d8..f39e7f14 100644 --- a/test/storage.test.ts +++ b/test/storage.test.ts @@ -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( From c9c90d17617c6ec7136d1b891ef0e7525e3399dd Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Tue, 5 May 2026 09:46:50 +0300 Subject: [PATCH 3/4] only owner access --- src/cli.ts | 4 ++-- src/commands.ts | 18 +++++++++--------- test/storage.test.ts | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index 174083b4..c958ee8d 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -818,8 +818,8 @@ export async function createCLI() { program .command("createBucket") - .description("Create a new persistent-storage bucket gated by a single access list (chain inferred from RPC)") - .argument("", "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); diff --git a/src/commands.ts b/src/commands.ts index fdeb47fa..148b4e9d 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1799,17 +1799,17 @@ export class Commands { public async createBucket(args: string[]): Promise { 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, diff --git a/test/storage.test.ts b/test/storage.test.ts index f39e7f14..c3335e64 100644 --- a/test/storage.test.ts +++ b/test/storage.test.ts @@ -122,4 +122,43 @@ 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 be denied access to the no-ACL bucket", async function () { + const bobOutput = await runCommandAs( + BOB_KEY, + `npm run cli listFilesInBucket ${ownerOnlyBucketId}` + ); + expect(bobOutput).to.not.include(fileName); + expect(bobOutput).to.match(/Error listing files|forbidden|unauthor|denied|not allowed/i); + }); + }); }); From 4ae793e30c26be8441c6e4095252e51114a7cf30 Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Tue, 5 May 2026 09:57:22 +0300 Subject: [PATCH 4/4] fix test --- test/storage.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/storage.test.ts b/test/storage.test.ts index c3335e64..d38a0dcf 100644 --- a/test/storage.test.ts +++ b/test/storage.test.ts @@ -152,13 +152,12 @@ describe("Ocean CLI Persistent Storage", function () { expect(listOutput).to.not.match(/Error listing files/i); }); - it("Bob (not the owner) should be denied access to the no-ACL bucket", async function () { + 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); - expect(bobOutput).to.match(/Error listing files|forbidden|unauthor|denied|not allowed/i); }); }); });