Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow web5.connect to work with a custom UserAgent #949

Open
sondreb opened this issue Oct 8, 2024 · 9 comments
Open

Allow web5.connect to work with a custom UserAgent #949

sondreb opened this issue Oct 8, 2024 · 9 comments
Labels
good first issue Good for newcomers small

Comments

@sondreb
Copy link

sondreb commented Oct 8, 2024

Note: @shamilovtim's Additions
Users want to be able to provide custom optionality to the UserAgent used by Web5.connect
We should be able to do this without bloating the params and argument drilling all of the params through multiple methods
Therefore we could allow users to pass a custom Web5 User Agent in order to solve this problem
This should eliminate the agentVault param


For example, to add dataPath as a parameter for Web5.connect() method. The dataPath should be forwarded to this request within the connect method:

const userAgent = await Web5UserAgent.create({ agentVault });

If this create method is provided with dataPath, it could be possible to have separate databases locally on the same app.

@bnonni
Copy link
Contributor

bnonni commented Oct 9, 2024

Are you asking to bubble up dataPath as a direct arg in the Web5.connect() method call? Forgive me if I'm misunderstanding, but I'm pretty sure you don't need to add dataPath to .connect to achieve this. You use await Web5UserAgent.create() to do the same thing.

public static async create({
dataPath = 'DATA/AGENT',
agentDid, agentVault, cryptoApi, didApi, dwnApi, identityApi, keyManager, permissionsApi, rpcClient, syncApi
}: Partial<AgentParams> = {}
): Promise<Web5UserAgent> {

Examples

  1. Multiple agents in one DATA folder
const agent0 = await Web5UserAgent.create({ dataPath: 'DATA/AGENT_0' });
const agent1 = await Web5UserAgent.create({ dataPath: 'DATA/AGENT_1' });
  1. Multiple DATA folders each with its own agent
const agent0 = await Web5UserAgent.create({ dataPath: 'DATA_0/AGENT' });
const agent1 = await Web5UserAgent.create({ dataPath: 'DATA_1/AGENT' });
  1. Passing a custom HdIdentityVault
const dataPath0 = 'DATA/AGENT_0';
const store0 = new LevelStore<string, string>({ location: `${dataPath0}/VAULT_STORE` });
const agentVault0 = new HdIdentityVault({  store: store0 });
const agent0 = await Web5UserAgent.create({ dataPath: dataPath0 });

const dataPath1 = 'DATA/AGENT_1';
const store1 = new LevelStore<string, string>({ location: `${dataPath1}/VAULT_STORE` });
const agentVault1 = new HdIdentityVault({  store: store1 });
const agent1 = await Web5UserAgent.create({ dataPath: dataPath1, agentVault: agentVault1 });

Example 3 is redundant / unneeded if you don't want to pass your own custom vault because the dataPath arg in .create gets passed down to a new HdIdentityVault with a LevelStore.

agentVault ??= new HdIdentityVault({
keyDerivationWorkFactor : 210_000,
store : new LevelStore<string, string>({ location: `${dataPath}/VAULT_STORE` })
});

However, if you want to pass your own custom vault, Example 3 is how you would do it.

@sondreb
Copy link
Author

sondreb commented Oct 10, 2024

Are you asking to bubble up dataPath as a direct arg in the Web5.connect() method call?

Yes, just make it easier for consumers of the library to supple it, without having to replicate some of the logic within the connect method. Thanks for the examples given👍

@bnonni
Copy link
Contributor

bnonni commented Oct 14, 2024

Are you asking to bubble up dataPath as a direct arg in the Web5.connect() method call?

Yes, just make it easier for consumers of the library to supple it, without having to replicate some of the logic within the connect method. Thanks for the examples given👍

@sondreb I understand. Makes sense. Obv I can't speak for the web5-js dev team, but speaking for myself, if I were them, I'd want to avoid overloading .connect method. It already has a sprawling list of args and does a LOT.

static async connect({
agent,
agentVault,
connectedDid,
password,
recoveryPhrase,
sync,
techPreview,
didCreateOptions,
registration,
walletConnectOptions,
}: Web5ConnectOptions = {}): Promise<Web5ConnectResult> {

But maybe adding it to one of the current args objects would solve your problem and keep the interface intact.

For example, the didCreateOptions object

export type DidCreateOptions = {
  /** Override default dwnEndpoints provided during DID creation. */
  dwnEndpoints?: string[];
 agentDataPath?: string; // Pass a custom dataPath down to Web5UserAgent.create and new HdIdentityVault
}

This small change would keep the .connect method arg interface consistent across versions while adding this optional var to pass into didCreateOptions to achieve your desired outcome.

Example implementation

const connection0 = await Web5.connect({
    password: 'password0',
    didCreateOptions: { agentDataPath: 'USER0_DATA/AGENT' } // or whatever you want
});

const connection1 = await Web5.connect({
    password: 'password1',
    didCreateOptions: { agentDataPath: 'DATA/USER_AGENT_1' }
});

From personal experience, this will move faster if you take the initiative to write the code and submit a PR :) Happy to collab with you on it in Discord if you want. Just lmk.

@sondreb
Copy link
Author

sondreb commented Oct 14, 2024

Thanks for the reply @bnonni, though the connect function is already implemented using a structured parameter and doesn't require additional connect overloads. JavaScript doesn't support function overloading; your point would be valid if it was using basic arguments.

It's not a good alternative to put it on didCreateOptions, as this is not related to the DID; but the DWN.

Should be fairly easy to make a PR for this, you could give it a go if you want to, and I'll review and help?

@bnonni
Copy link
Contributor

bnonni commented Oct 14, 2024

@sondreb Sorry, I misused the term overload. I simply meant, that this method has a lot of args already, and that can make the interface messy and confusing leading to bad dev experience, unexpected user behavior and/or unexpected use cases resulting in frustration. My comment was more of an intuition-based suggestion from a code design standpoint, less of a recommendation. That intuition comes from the fact that the .connect method is designed to be the entry point for the Web5 platform API, and when I design and implement APIs (web or otherwise) my top priority / goal is to keep the interface clean, simple and easy to use.

Regardless, I'll let you take lead on it. Feel free to ping me if you'd like review and help.

@shamilovtim
Copy link
Contributor

shamilovtim commented Oct 23, 2024

@sondreb If we let you pass your own userAgent into the method would that solve this for you? I think it would be the most elegant solution here. Then you can add whatever optionality / params to your UserAgent that you want. It would also be healthier for the codebase since it would eliminate the agentVault param.

@sondreb
Copy link
Author

sondreb commented Oct 24, 2024

Maybe it would be enough, at least making it a little bit easier than it is now. Thanks!

@shamilovtim shamilovtim changed the title Allow dataPath to be provided for Web5.connect Allow web5.connect to work with a custom UserAgent Oct 24, 2024
@shamilovtim shamilovtim self-assigned this Oct 24, 2024
@shamilovtim
Copy link
Contributor

@sondreb open for PRs until someone else gets to it if it's a priority for you. otherwise one of myself or @LiranCohen could eventually solve.

@shamilovtim shamilovtim removed their assignment Oct 24, 2024
@shamilovtim shamilovtim moved this to Backlog in Web5 Roadmap Oct 24, 2024
@shamilovtim shamilovtim added the good first issue Good for newcomers label Oct 24, 2024
@bnonni
Copy link
Contributor

bnonni commented Nov 1, 2024

@sondreb open for PRs until someone else gets to it if it's a priority for you. otherwise one of myself or @LiranCohen could eventually solve.

I'll give this a shot today.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers small
Projects
Status: Backlog
Development

No branches or pull requests

3 participants