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

Updated secret tests and added exectution validation #80

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
134 changes: 93 additions & 41 deletions packages/sdk-js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { BoolValue } from "google-protobuf/google/protobuf/wrappers_pb";
import { Timestamp } from "google-protobuf/google/protobuf/timestamp_pb";
import Workflow, { WorkflowProps } from "./models/workflow";
import Edge, { EdgeProps } from "./models/edge";
import Execution from "./models/execution";
import Execution, { ExecutionProps } from "./models/execution";
import Step, { StepProps } from "./models/step";
import NodeFactory from "./models/node/factory";
import TriggerFactory from "./models/trigger/factory";
import Secret from "./models/secret";
import type {
GetKeyRequestApiKey,
GetKeyRequestSignature,
Expand All @@ -25,9 +25,8 @@ import {
GetExecutionsRequest,
GetWorkflowsRequest,
DEFAULT_LIMIT,
ListSecretRequest,
ListSecretResponse,
DeleteSecretRequest,
SecretRequestOptions,
} from "./types";

import TriggerMetadata, {
Expand Down Expand Up @@ -77,7 +76,7 @@ class BaseClient {
}

/**
* The API key could retrieve a wallets authKey by skipping its signature verification
* The API key could retrieve a wallet's authKey by skipping its signature verification
* @param chainId - The chain id
* @param address - The address of the EOA wallet
* @param issuedAt - The issued at timestamp
Expand Down Expand Up @@ -153,7 +152,7 @@ class BaseClient {
}

/**
* Get the auth key if its set in the client
* Get the auth key if it's set in the client
* @returns {string | undefined} - The auth key
*/
public getAuthKey(): string | undefined {
Expand All @@ -169,7 +168,7 @@ class BaseClient {
}

/**
* Get the factory address if its set in the client
* Get the factory address if it's set in the client
* @returns {string | undefined} - The factory address
*/
public getFactoryAddress(): string | undefined {
Expand Down Expand Up @@ -507,10 +506,22 @@ export default class Client extends BaseClient {
}

async createSecret(
secret: Secret,
options?: RequestOptions
name: string,
value: string,
options?: SecretRequestOptions
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The interface is changed to this style for Secret functions.

options?: {workflowId?: string, orgId?: string}

): Promise<boolean> {
const request = secret.toRequest();
const request = new avs_pb.CreateOrUpdateSecretReq();

request.setName(name);
request.setSecret(value);

if (options?.workflowId) {
request.setWorkflowId(options.workflowId);
}

if (options?.orgId) {
request.setOrgId(options.orgId);
}

const result = await this.sendGrpcRequest<
BoolValue,
Expand All @@ -520,37 +531,91 @@ export default class Client extends BaseClient {
return result.getValue();
}

/**
* Update an existing secret; the secret is updated in the user scope by default, derived from the auth key.
* @param secret - The secret object containing updated information
* @param options - Request options, including workflowId and orgId for scoping
* @returns {Promise<boolean>} - Whether the secret was successfully updated
*/
async updateSecret(
name: string,
value: string,
options?: SecretRequestOptions
): Promise<boolean> {
const request = new avs_pb.CreateOrUpdateSecretReq();

request.setName(name);
request.setSecret(value);

if (options?.workflowId) {
request.setWorkflowId(options.workflowId);
}

if (options?.orgId) {
request.setOrgId(options.orgId);
}

const result = await this.sendGrpcRequest<
BoolValue,
avs_pb.CreateOrUpdateSecretReq
>("updateSecret", request, options);

return result.getValue();
}

/**
* Retrieve a list of secrets; secrets can be filtered by workflowId or orgId.
* @param params - Parameters for listing secrets
* @param options - Request options, including workflowId and orgId for filtering
* @returns {Promise<ListSecretResponse[]>} - The list of secrets
*/
async listSecrets(
params: ListSecretRequest,
options?: RequestOptions
options?: SecretRequestOptions
): Promise<ListSecretResponse[]> {
const request = new avs_pb.ListSecretsReq();
if (params?.workflowId) {
request.setWorkflowId(params.workflowId);

if (options?.workflowId) {
request.setWorkflowId(options.workflowId);
}

if (options?.orgId) {
// TODO: wait for the AVS to support orgId in ListSecrets
// request.setOrgId(options.orgId);
}

const result = await this.sendGrpcRequest<
avs_pb.ListSecretsResp,
avs_pb.ListSecretsReq
>("listSecrets", request, options);

return result.getItemsList().map((item) => {
return {
name: item.getName(),
workflowId: item.getWorkflowId(),
orgId: item.getOrgId(),
};
});
return result.getItemsList().map((item) => ({
name: item.getName(),
workflowId: item.getWorkflowId(),
orgId: item.getOrgId(),
}));
}

/**
* Delete a secret by its name; by default, the secret is deleted from the user scope, derived from the auth key
* @param name - The name of the secret
* @param options - Request options
* @param options.workflowId - The workflow id; if specified, the secret will be deleted from the workflow scope
* @param options.orgId - The organization id; if specified, the secret will be deleted from the organization scope
* @returns {Promise<boolean>} - Whether the secret was successfully deleted
*/
async deleteSecret(
params: DeleteSecretRequest,
options?: RequestOptions
name: string,
options?: SecretRequestOptions
): Promise<boolean> {
const request = new avs_pb.DeleteSecretReq();
request.setName(params.name);
if (params?.workflowId) {
request.setWorkflowId(params.workflowId);
request.setName(name);

if (options?.workflowId) {
request.setWorkflowId(options.workflowId);
}

if (options?.orgId) {
request.setOrgId(options.orgId);
}

const result = await this.sendGrpcRequest<
Expand All @@ -560,26 +625,13 @@ export default class Client extends BaseClient {

return result.getValue();
}

async updateSecret(
secret: Secret,
options?: RequestOptions
): Promise<boolean> {
const request = secret.toRequest();

const result = await this.sendGrpcRequest<
BoolValue,
avs_pb.CreateOrUpdateSecretReq
>("updateSecret", request, options);
return result.getValue();
}
}

// Export types for easier use
export * from "./types";
export * from "./models/node/factory";
export * from "./models/trigger/factory";

export { Workflow, Edge, Execution, NodeFactory, TriggerFactory, Secret };
export { Workflow, Edge, Execution, Step, NodeFactory, TriggerFactory };

export type { WorkflowProps, EdgeProps };
export type { WorkflowProps, EdgeProps, ExecutionProps, StepProps };
64 changes: 32 additions & 32 deletions packages/sdk-js/src/models/secret.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
import * as avs_pb from "@/grpc_codegen/avs_pb";
// import * as avs_pb from "@/grpc_codegen/avs_pb";

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Workflow, Node classes are used to serialize and format data from grpc, but for Secret we don’t have complex needs, so this file is not used yet.

export type SecretProps = {
name: string;
secret: string;
workflowId?: string;
orgId?: string;
};
// export type SecretProps = {
// name: string;
// secret: string;
// workflowId?: string;
// orgId?: string;
// };

class Secret implements SecretProps {
name: string;
secret: string;
workflowId?: string;
orgId?: string;
// class Secret implements SecretProps {
// name: string;
// secret: string;
// workflowId?: string;
// orgId?: string;

constructor(props: SecretProps) {
this.name = props.name;
this.secret = props.secret;
this.workflowId = props.workflowId;
this.orgId = props.orgId;
}
// constructor(props: SecretProps) {
// this.name = props.name;
// this.secret = props.secret;
// this.workflowId = props.workflowId;
// this.orgId = props.orgId;
// }

toRequest(): avs_pb.CreateOrUpdateSecretReq {
const request = new avs_pb.CreateOrUpdateSecretReq();
// toRequest(): avs_pb.CreateOrUpdateSecretReq {
// const request = new avs_pb.CreateOrUpdateSecretReq();

request.setName(this.name);
request.setSecret(this.secret);
if (this.orgId) {
request.setOrgId(this.orgId);
}
if (this.workflowId) {
request.setWorkflowId(this.workflowId);
}
// request.setName(this.name);
// request.setSecret(this.secret);
// if (this.orgId) {
// request.setOrgId(this.orgId);
// }
// if (this.workflowId) {
// request.setWorkflowId(this.workflowId);
// }

return request;
}
}
// return request;
// }
// }

export default Secret;
// export default Secret;
13 changes: 4 additions & 9 deletions packages/sdk-js/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,11 @@ export const ExecutionStatus = avs_pb.ExecutionStatus;

export interface ListSecretResponse {
name: string;
workflowId: string;
orgId: string;
}

export interface ListSecretRequest {
workflowId?: string;
orgId?: string;
}

export interface DeleteSecretRequest {
name: string;
workflowId: string;
orgId: string;
export interface SecretRequestOptions extends RequestOptions {
workflowId?: string;
orgId?: string;
}
14 changes: 0 additions & 14 deletions tests/auth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,20 +218,6 @@ describe("Authentication Tests", () => {
expect(res2).toHaveProperty("factory", FACTORY_ADDRESS);
});

test("getWallets works with options.authKey", async () => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test has the exactly same name with the previous one, so I removed it.

I think it’s trying to test a default value salt:0, but there’s already a salt:123 created from the previous tests. We don’t have a way to reset the smart wallet response array yet.

const wallets = await client.getWallets({ authKey: authKeyViaAPI });
expect(wallets.length).toBeGreaterThanOrEqual(1);

expect(wallets[0]).toHaveProperty("address");
expect(wallets[0]).toHaveProperty("salt", "0");
expect(wallets[0]).toHaveProperty("factory", FACTORY_ADDRESS);

const wallets2 = await client.getWallets({
authKey: authKeyViaSignature,
});
expect(wallets2.length).toBeGreaterThanOrEqual(1);
});

test("createWorkflow works with options.authKey", async () => {
const wallet = await client.getWallet(
{ salt: "345" },
Expand Down
Loading
Loading