Skip to content

Commit 6e28a89

Browse files
committed
Trying different decorator implementations
1 parent 28fde3a commit 6e28a89

File tree

5 files changed

+53
-77
lines changed

5 files changed

+53
-77
lines changed

packages/lively-diamond/tsconfig.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
"compilerOptions": {
33
"declaration": true,
44
"declarationMap": true,
5-
"emitDecoratorMetadata": true,
65
"esModuleInterop": true,
7-
"experimentalDecorators": true,
86
"forceConsistentCasingInFileNames": true,
97
"lib": ["ESNext"],
108
"module": "commonjs",

packages/sdk-lively-contracts/src/lib/sdk/LivelyDiamondSDK.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ describe('livelyDiamondSDK', () => {
1212
describe('decorators', () => {
1313
describe('isValidNetwork', () => {
1414
it('should be false for invalid network', () => {
15-
// @ts-expect-error This is testing an invalid network so it should throw an error
1615
expect(() => isValidNetwork('mainnet2')).toBeFalsy;
1716
});
1817

@@ -72,7 +71,7 @@ describe('livelyDiamondSDK', () => {
7271
});
7372

7473
it('return account info if properly given private key', () => {
75-
const sdk2 = LivelyDiamondSDK.fromPK(validPK);
74+
const sdk2 = new LivelyDiamondSDK({ privateKey: validPK });
7675
console.log({ sdk2 });
7776
});
7877
});

packages/sdk-lively-contracts/src/lib/sdk/LivelyDiamondSDK.ts

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { PrivateKeyAccount } from 'viem';
22
import { privateKeyToAccount } from 'viem/accounts';
3-
import { isValidNetwork, isValidPrivateKey } from './shared/decorators.js';
3+
import { isValidNetwork, isValidPrivateKey, validate } from './shared/decorators.js';
44
import {
55
SupportedNetworks,
66
type LivelyDiamondSDKOptions,
@@ -22,56 +22,28 @@ const defaultOpts = {
2222
// bar: (error: Error) => void;
2323
// };
2424

25-
function ValidateOptions(target: any) {
26-
const originalConstructor = target.prototype.constructor;
27-
28-
function newConstructor(opts: LivelyDiamondSDKOptions = defaultOpts) {
29-
if (opts.network && !isValidNetwork(opts.network)) {
30-
throw new Error('Invalid network');
31-
}
32-
33-
if (opts.privateKey && !isValidPrivateKey(opts.privateKey)) {
34-
throw new Error('Invalid privateKey');
35-
}
36-
37-
originalConstructor.call(this, opts);
38-
}
39-
40-
target.prototype.constructor = newConstructor;
41-
}
42-
4325
// class LivelyDiamondSDK<T extends object> extends EventEmitter<EventTypes & T> {
4426

45-
@ValidateOptions
27+
@validate('network', isValidNetwork, { optional: true })
28+
@validate('privateKey', isValidPrivateKey, { optional: true })
4629
class LivelyDiamondSDK {
4730
network: SupportedNetworks | undefined;
4831
private account: PrivateKeyAccount | undefined;
4932

5033
constructor(opts: LivelyDiamondSDKOptions = defaultOpts) {
51-
// if (opts.network && !isValidNetwork(opts.network)) throw new Error('Invalid network');
52-
// if (opts.privateKey && !isValidPrivateKey(opts.privateKey)) throw new Error('Invalid PK');
53-
54-
// super();
55-
this.network = opts.network;
34+
this.network = opts?.network || SupportedNetworks.MAINNET;
5635
this.account = opts?.privateKey ? privateKeyToAccount(opts.privateKey) : undefined;
5736
}
5837

59-
static fromPK(privateKey: EthAddress, opts = { network: SupportedNetworks.MAINNET }) {
60-
if (!isValidPrivateKey(privateKey)) throw new Error('Invalid PK');
61-
if (opts.network && !isValidNetwork(opts.network)) throw new Error('Invalid network');
62-
63-
return new LivelyDiamondSDK({ network: opts.network, privateKey });
64-
}
65-
6638
// Read only properties
6739
public getAccount() {
6840
return this.account;
6941
}
7042

7143
// Write properties (needs a signer)
72-
public connectPK(privateKey: EthAddress) {
73-
if (!isValidPrivateKey(privateKey)) throw new Error('Invalid PK');
74-
this.account = privateKeyToAccount(privateKey);
44+
@validate('privateKey', isValidPrivateKey)
45+
public connectPK(opts: { privateKey: EthAddress }) {
46+
this.account = privateKeyToAccount(opts.privateKey);
7547
}
7648
}
7749

packages/sdk-lively-contracts/src/lib/sdk/shared/decorators.ts

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,59 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
12
import { privateKeyToAccount } from 'viem/accounts';
2-
import { SupportedNetworks, type EthAddress, type LivelyDiamondSDKOptions } from './types.js';
3+
import { SupportedNetworks } from './types.js';
34

4-
// NOTE: Need to get these working as actual decorators. Mainly having trouble with the constructor decorator for the class.
5-
6-
export function isValidNetwork(network: SupportedNetworks): boolean {
7-
if (!Object.values(SupportedNetworks).includes(network)) return false;
8-
return true;
5+
export function isValidNetwork(network?: unknown): boolean {
6+
return Boolean(typeof network === 'string' && Object.values(SupportedNetworks).includes(network));
97
}
108

11-
export function isValidPrivateKey(privateKey: EthAddress): boolean {
9+
export function isValidPrivateKey(privateKey?: unknown): boolean {
10+
if (typeof privateKey !== 'string' || !privateKey.startsWith('0x')) return false;
1211
try {
13-
privateKeyToAccount(privateKey);
12+
privateKeyToAccount(privateKey as `0x${string}`);
1413
return true;
1514
} catch (error) {
16-
return false;
1715
// throw new Error(`Invalid private key: ${(error as Error).message}`);
16+
return false;
1817
}
1918
}
2019

21-
// eslint-disable-next-line @typescript-eslint/ban-types
22-
export function Validate<T extends { new (...args: any[]): {} }>(constructor: T, ...args: any[]) {
23-
console.log({ constructor, args });
24-
return class extends constructor {
25-
isValidNetwork(network: SupportedNetworks): boolean {
26-
return isValidNetwork(network);
20+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
21+
export function validate<T extends abstract new (...args: any) => any>(
22+
field: string,
23+
validator: (v: unknown) => boolean,
24+
validateOptions: { optional?: boolean } = { optional: false }
25+
) {
26+
return function (
27+
target: any,
28+
context: ClassDecoratorContext<T> | ClassMethodDecoratorContext<T>
29+
): T | void {
30+
if (!context || context.kind === 'class') {
31+
// Maybe do this instead of wrapping?
32+
// context.addInitializer(function () {
33+
// if (!validator(this[field as keyof T])) {
34+
// throw new Error(`Invalid ${String(field)}`);
35+
// }
36+
// });
37+
const wrapper = function (...args: any) {
38+
const opts = args?.[0];
39+
if ((validateOptions.optional && !opts?.[field]) || validator(opts?.[field])) {
40+
return new target(...args);
41+
}
42+
throw new Error(`Invalid ${String(field)}`);
43+
};
44+
wrapper.prototype = target.prototype;
45+
return wrapper as unknown as T;
46+
}
47+
if (context.kind === 'function') {
48+
const wrapper = function (...args: any) {
49+
const opts = args?.[0];
50+
if ((validateOptions.optional && !opts?.[field]) || validator(opts?.[field])) {
51+
return target(...args);
52+
}
53+
throw new Error(`Invalid ${String(field)}`);
54+
};
55+
wrapper.prototype = target.prototype;
56+
return wrapper as unknown as T;
2757
}
2858
};
2959
}
30-
31-
// /**
32-
// * Check if the options passed are valid
33-
// * @param opts All valid configuration options
34-
// * @returns void
35-
// * @throws Error if any of the options are invalid
36-
// */
37-
// export function isValidOptions(opts?: Partial<LivelyDiamondSDKOptions>): boolean {
38-
// console.log(`Inside isValidOptions: ${opts}`);
39-
40-
// if (!opts) return true;
41-
42-
// let isValid: boolean | undefined = undefined;
43-
44-
// if (opts?.privateKey) isValid ??= isValidPrivateKey(opts.privateKey);
45-
// if (opts?.network) isValid ??= isValidNetwork(opts.network);
46-
47-
// if (!isValid) isValid ??= false;
48-
49-
// return isValid;
50-
// }

packages/sdk-lively-contracts/tsconfig.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
"moduleResolution": "NodeNext",
1212
"ignoreDeprecations": "5.0",
1313
"target": "ES5",
14-
"experimentalDecorators": true,
15-
"emitDecoratorMetadata": true,
1614
"esModuleInterop": true
1715
},
1816
"ts-node": {

0 commit comments

Comments
 (0)