@nucypher/taco-auth 0.3.0-alpha.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/cjs/auth-sig.d.ts +10 -8
  2. package/dist/cjs/auth-sig.js +4 -5
  3. package/dist/cjs/auth-sig.js.map +1 -1
  4. package/dist/cjs/providers/eip1271/auth.d.ts +47 -0
  5. package/dist/cjs/providers/eip1271/auth.js +15 -0
  6. package/dist/cjs/providers/eip1271/auth.js.map +1 -0
  7. package/dist/cjs/providers/eip1271/eip1271.d.ts +34 -0
  8. package/dist/cjs/providers/eip1271/eip1271.js +53 -0
  9. package/dist/cjs/providers/eip1271/eip1271.js.map +1 -0
  10. package/dist/cjs/providers/eip4361/auth.d.ts +24 -0
  11. package/dist/cjs/providers/eip4361/auth.js +25 -0
  12. package/dist/cjs/providers/eip4361/auth.js.map +1 -0
  13. package/dist/cjs/providers/eip4361/eip4361.d.ts +71 -5
  14. package/dist/cjs/providers/eip4361/eip4361.js +89 -30
  15. package/dist/cjs/providers/eip4361/eip4361.js.map +1 -1
  16. package/dist/cjs/providers/eip4361/external-eip4361.d.ts +35 -4
  17. package/dist/cjs/providers/eip4361/external-eip4361.js +56 -7
  18. package/dist/cjs/providers/eip4361/external-eip4361.js.map +1 -1
  19. package/dist/cjs/providers/index.d.ts +3 -0
  20. package/dist/cjs/providers/index.js +4 -0
  21. package/dist/cjs/providers/index.js.map +1 -1
  22. package/dist/cjs/storage.d.ts +6 -4
  23. package/dist/cjs/storage.js +4 -3
  24. package/dist/cjs/storage.js.map +1 -1
  25. package/dist/es/auth-sig.d.ts +10 -8
  26. package/dist/es/auth-sig.js +3 -4
  27. package/dist/es/auth-sig.js.map +1 -1
  28. package/dist/es/providers/eip1271/auth.d.ts +47 -0
  29. package/dist/es/providers/eip1271/auth.js +12 -0
  30. package/dist/es/providers/eip1271/auth.js.map +1 -0
  31. package/dist/es/providers/eip1271/eip1271.d.ts +34 -0
  32. package/dist/es/providers/eip1271/eip1271.js +49 -0
  33. package/dist/es/providers/eip1271/eip1271.js.map +1 -0
  34. package/dist/es/providers/eip4361/auth.d.ts +24 -0
  35. package/dist/es/providers/eip4361/auth.js +22 -0
  36. package/dist/es/providers/eip4361/auth.js.map +1 -0
  37. package/dist/es/providers/eip4361/eip4361.d.ts +71 -5
  38. package/dist/es/providers/eip4361/eip4361.js +87 -28
  39. package/dist/es/providers/eip4361/eip4361.js.map +1 -1
  40. package/dist/es/providers/eip4361/external-eip4361.d.ts +35 -4
  41. package/dist/es/providers/eip4361/external-eip4361.js +54 -5
  42. package/dist/es/providers/eip4361/external-eip4361.js.map +1 -1
  43. package/dist/es/providers/index.d.ts +3 -0
  44. package/dist/es/providers/index.js +2 -0
  45. package/dist/es/providers/index.js.map +1 -1
  46. package/dist/es/storage.d.ts +6 -4
  47. package/dist/es/storage.js +4 -3
  48. package/dist/es/storage.js.map +1 -1
  49. package/dist/tsconfig.cjs.tsbuildinfo +1 -1
  50. package/dist/tsconfig.es.tsbuildinfo +1 -1
  51. package/package.json +5 -5
@@ -1,19 +1,49 @@
1
- import { generateNonce, SiweMessage } from 'siwe';
1
+ import { SiweMessage } from 'siwe';
2
2
  import { LocalStorage } from '../../storage';
3
- import { EIP4361_AUTH_METHOD } from './common';
4
- export const USER_ADDRESS_PARAM_DEFAULT = ':userAddress';
5
- const ERR_MISSING_SIWE_PARAMETERS = 'Missing default SIWE parameters';
3
+ import { EIP4361_AUTH_METHOD, eip4361AuthSignatureSchema, } from './auth';
4
+ export const FRESHNESS_IN_MILLISECONDS = 2 * 60 * 60 * 1000;
5
+ const TACO_DEFAULT_DOMAIN = 'taco.build';
6
+ const TACO_DEFAULT_URI = 'https://taco.build';
7
+ /**
8
+ * Implements Sign-In with Ethereum (EIP-4361/SIWE) authentication by managing SIWE message lifecycle.
9
+ *
10
+ * This provider handles:
11
+ * - Creating and signing new SIWE messages
12
+ * - Storing signed messages in local storage
13
+ * - Retrieving and validating stored messages
14
+ * - Automatically refreshing expired messages
15
+ *
16
+ * Messages are valid for 2 hours from creation and stored locally keyed by the signer's address.
17
+ *
18
+ * @implements {AuthProvider}
19
+ */
6
20
  export class EIP4361AuthProvider {
7
21
  provider;
8
22
  signer;
9
23
  storage;
10
24
  providerParams;
11
- constructor(
12
- // TODO: We only need the provider to fetch the chainId, consider removing it
13
- provider, signer, providerParams) {
25
+ /**
26
+ * Creates a new EIP4361AuthProvider instance.
27
+ *
28
+ * @param provider - Ethers provider used to fetch the current chainId
29
+ * @param signer - Ethers signer used to sign SIWE messages
30
+ * @param providerParams - Optional SIWE message configuration
31
+ * @param providerParams.domain - Domain name for the signing request (e.g. 'app.example.com').
32
+ * Defaults to current website domain or 'taco.build'
33
+ * @param providerParams.uri - Full URI of signing request origin (e.g. 'https://app.example.com').
34
+ * Defaults to current website URL or 'https://taco.build'
35
+ *
36
+ * The SIWE message will include:
37
+ * - A human-readable statement: "{domain} wants you to sign in with your Ethereum account: {address}"
38
+ * - Version: "1"
39
+ * - 2 hour expiration from creation time
40
+ * - Chain ID from the provided provider
41
+ * - Nonce: Auto-generated
42
+ */
43
+ constructor(provider, signer, providerParams) {
14
44
  this.provider = provider;
15
45
  this.signer = signer;
16
- this.storage = new LocalStorage();
46
+ this.storage = new LocalStorage(eip4361AuthSignatureSchema);
17
47
  if (providerParams) {
18
48
  this.providerParams = providerParams;
19
49
  }
@@ -21,6 +51,14 @@ export class EIP4361AuthProvider {
21
51
  this.providerParams = this.getDefaultParameters();
22
52
  }
23
53
  }
54
+ /**
55
+ * Gets default domain and URI parameters based on runtime environment.
56
+ *
57
+ * @returns Default parameters object with domain and uri
58
+ * @returns.domain - Host domain from window.location or 'taco.build'
59
+ * @returns.uri - Origin URL from window.location or 'https://taco.build'
60
+ * @private
61
+ */
24
62
  getDefaultParameters() {
25
63
  if (typeof window !== 'undefined') {
26
64
  // If we are in a browser environment, we can get the domain and uri from the window object
@@ -29,45 +67,65 @@ export class EIP4361AuthProvider {
29
67
  uri: window.location?.origin,
30
68
  };
31
69
  }
32
- // If not, we have no choice but to throw an error
33
- throw new Error(ERR_MISSING_SIWE_PARAMETERS);
70
+ // not in a browser environment, use hardcoded defaults
71
+ return {
72
+ domain: TACO_DEFAULT_DOMAIN,
73
+ uri: TACO_DEFAULT_URI,
74
+ };
34
75
  }
76
+ /**
77
+ * Gets a valid auth signature, either from storage or by creating a new one.
78
+ *
79
+ * Process:
80
+ * 1. Check local storage for existing signature for the signer's address
81
+ * 2. If found, verify the signature and expiration time
82
+ * 3. If verification fails or no signature exists, create and store a new one
83
+ * 4. Return the valid signature
84
+ *
85
+ * @returns Promise resolving to a valid EIP-4361 auth signature containing:
86
+ * @returns.signature - The signed SIWE message
87
+ * @returns.address - The signer's Ethereum address
88
+ * @returns.scheme - Authentication scheme ('eip4361')
89
+ * @returns.typedData - Original SIWE message string
90
+ */
35
91
  async getOrCreateAuthSignature() {
36
92
  const address = await this.signer.getAddress();
37
93
  const storageKey = `eth-${EIP4361_AUTH_METHOD}-message-${address}`;
38
94
  // If we have a signature in localStorage, return it
39
95
  const maybeSignature = this.storage.getAuthSignature(storageKey);
40
96
  if (maybeSignature) {
41
- // check whether older than node freshness requirement
42
- if (this.isMessageExpired(maybeSignature.typedData)) {
97
+ const siweMessage = new SiweMessage(maybeSignature.typedData);
98
+ try {
99
+ // check message validity specifically here for the `expirationTime`.
100
+ await siweMessage.verify({ signature: maybeSignature.signature });
101
+ return maybeSignature;
102
+ }
103
+ catch (e) {
43
104
  // clear signature so that it will be recreated and stored
44
105
  this.storage.clear(storageKey);
45
106
  }
46
- else {
47
- return maybeSignature;
48
- }
49
107
  }
50
108
  // If at this point we didn't return, we need to create a new message
51
109
  const authMessage = await this.createSIWEAuthMessage();
52
110
  this.storage.setAuthSignature(storageKey, authMessage);
53
111
  return authMessage;
54
112
  }
55
- isMessageExpired(message) {
56
- const siweMessage = new SiweMessage(message);
57
- if (!siweMessage.issuedAt) {
58
- // don't expect to ever happen; but just in case
59
- return false;
60
- }
61
- const twoHourWindow = new Date(siweMessage.issuedAt);
62
- twoHourWindow.setHours(twoHourWindow.getHours() + 2);
63
- const now = new Date();
64
- return twoHourWindow < now;
65
- }
113
+ /**
114
+ * Creates and signs a new SIWE authentication message.
115
+ *
116
+ * Process:
117
+ * 1. Get signer's address and current chain ID
118
+ * 2. Create SIWE message with 2 hour expiration
119
+ * 3. Sign message with signer
120
+ * 4. Return signed auth signature object
121
+ *
122
+ * @returns Promise resolving to newly created and signed auth signature
123
+ * @private
124
+ */
66
125
  async createSIWEAuthMessage() {
67
126
  const address = await this.signer.getAddress();
68
127
  const { domain, uri } = this.providerParams;
69
128
  const version = '1';
70
- const nonce = generateNonce();
71
129
  const chainId = (await this.provider.getNetwork()).chainId;
72
130
  const siweMessage = new SiweMessage({
73
131
  domain,
@@ -75,8 +133,9 @@ export class EIP4361AuthProvider {
75
133
  statement: `${domain} wants you to sign in with your Ethereum account: ${address}`,
76
134
  uri,
77
135
  version,
78
- nonce,
79
136
  chainId,
137
+ // set the expirationTime to 2 hours from now
138
+ expirationTime: new Date(Date.now() + FRESHNESS_IN_MILLISECONDS).toISOString(),
80
139
  });
81
140
  const scheme = EIP4361_AUTH_METHOD;
82
141
  const message = siweMessage.prepareMessage();
@@ -1 +1 @@
1
- {"version":3,"file":"eip4361.js","sourceRoot":"","sources":["../../../../src/providers/eip4361/eip4361.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"eip4361.js","sourceRoot":"","sources":["../../../../src/providers/eip4361/eip4361.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,41 @@
1
- import { AuthSignature } from '../../auth-sig';
2
- export declare const USER_ADDRESS_PARAM_EXTERNAL_EIP4361 = ":userAddressExternalEIP4361";
3
- export declare class SingleSignOnEIP4361AuthProvider {
1
+ import { AuthProvider } from '../../auth-provider';
2
+ import { EIP4361AuthSignature } from './auth';
3
+ /**
4
+ * SingleSignOnEIP4361AuthProvider handles Sign-In with Ethereum (EIP-4361/SIWE) authentication
5
+ * using an existing SIWE message and signature.
6
+ *
7
+ * This provider validates and reuses an existing SIWE message and signature rather than generating new ones.
8
+ * It's useful for implementing single sign-on flows where the SIWE authentication was performed elsewhere.
9
+ */
10
+ export declare class SingleSignOnEIP4361AuthProvider implements AuthProvider {
4
11
  private readonly existingSiweMessage;
5
12
  readonly address: string;
6
13
  private readonly signature;
14
+ /**
15
+ * Creates a new SingleSignOnEIP4361AuthProvider from an existing SIWE message and signature.
16
+ *
17
+ * @param existingSiweMessage - The existing SIWE message string to validate and reuse
18
+ * @param signature - The signature corresponding to the SIWE message
19
+ * @returns A new SingleSignOnEIP4361AuthProvider instance
20
+ * @throws {Error} If signature verification fails or message parameters are invalid
21
+ */
7
22
  static fromExistingSiweInfo(existingSiweMessage: string, signature: string): Promise<SingleSignOnEIP4361AuthProvider>;
23
+ /**
24
+ * Private constructor - use fromExistingSiweInfo() to create instances.
25
+ *
26
+ * @param existingSiweMessage - The validated SIWE message string
27
+ * @param address - The Ethereum address that signed the message
28
+ * @param signature - The validated signature
29
+ */
8
30
  private constructor();
9
- getOrCreateAuthSignature(): Promise<AuthSignature>;
31
+ /**
32
+ * Returns the existing auth signature after re-validating it.
33
+ *
34
+ * This method verifies that the stored signature and message are still valid
35
+ * before returning them as an EIP4361AuthSignature object.
36
+ *
37
+ * @returns {Promise<EIP4361AuthSignature>} The validated authentication signature
38
+ * @throws {Error} If signature verification fails
39
+ */
40
+ getOrCreateAuthSignature(): Promise<EIP4361AuthSignature>;
10
41
  }
@@ -1,24 +1,73 @@
1
1
  import { SiweMessage } from 'siwe';
2
- import { EIP4361_AUTH_METHOD } from './common';
3
- export const USER_ADDRESS_PARAM_EXTERNAL_EIP4361 = ':userAddressExternalEIP4361';
2
+ import { EIP4361_AUTH_METHOD } from './auth';
3
+ import { FRESHNESS_IN_MILLISECONDS } from './eip4361';
4
+ async function generateAndVerifySiweMessage(message, signature) {
5
+ const siweMessage = new SiweMessage(message);
6
+ // this will trigger validation for the signature and all parameters (`expirationTime`, `notBefore`...).
7
+ await siweMessage.verify({ signature });
8
+ const twoHoursBeforeNow = new Date(Date.now() - FRESHNESS_IN_MILLISECONDS);
9
+ if (!siweMessage.issuedAt) {
10
+ throw new Error(
11
+ // this should never happen
12
+ `The SIWE message is missing an \`issuedAt\` field and would be rejected by TACo nodes.`);
13
+ }
14
+ if (new Date(siweMessage.issuedAt) < twoHoursBeforeNow) {
15
+ throw new Error(`The SIWE message was issued more than 2 hours ago and would be rejected by TACo nodes.`);
16
+ }
17
+ const now = new Date();
18
+ if (new Date(siweMessage.issuedAt) > now) {
19
+ throw new Error(`The SIWE message was issued at a future datetime: ${siweMessage.issuedAt} and would be rejected by TACo nodes.`);
20
+ }
21
+ return siweMessage;
22
+ }
23
+ /**
24
+ * SingleSignOnEIP4361AuthProvider handles Sign-In with Ethereum (EIP-4361/SIWE) authentication
25
+ * using an existing SIWE message and signature.
26
+ *
27
+ * This provider validates and reuses an existing SIWE message and signature rather than generating new ones.
28
+ * It's useful for implementing single sign-on flows where the SIWE authentication was performed elsewhere.
29
+ */
4
30
  export class SingleSignOnEIP4361AuthProvider {
5
31
  existingSiweMessage;
6
32
  address;
7
33
  signature;
34
+ /**
35
+ * Creates a new SingleSignOnEIP4361AuthProvider from an existing SIWE message and signature.
36
+ *
37
+ * @param existingSiweMessage - The existing SIWE message string to validate and reuse
38
+ * @param signature - The signature corresponding to the SIWE message
39
+ * @returns A new SingleSignOnEIP4361AuthProvider instance
40
+ * @throws {Error} If signature verification fails or message parameters are invalid
41
+ */
8
42
  static async fromExistingSiweInfo(existingSiweMessage, signature) {
9
- // validation
10
- const siweMessage = new SiweMessage(existingSiweMessage);
11
- await siweMessage.verify({ signature });
43
+ const siweMessage = await generateAndVerifySiweMessage(existingSiweMessage, signature);
12
44
  // create provider
13
45
  const authProvider = new SingleSignOnEIP4361AuthProvider(siweMessage.prepareMessage(), siweMessage.address, signature);
14
46
  return authProvider;
15
47
  }
48
+ /**
49
+ * Private constructor - use fromExistingSiweInfo() to create instances.
50
+ *
51
+ * @param existingSiweMessage - The validated SIWE message string
52
+ * @param address - The Ethereum address that signed the message
53
+ * @param signature - The validated signature
54
+ */
16
55
  constructor(existingSiweMessage, address, signature) {
17
56
  this.existingSiweMessage = existingSiweMessage;
18
57
  this.address = address;
19
58
  this.signature = signature;
20
59
  }
60
+ /**
61
+ * Returns the existing auth signature after re-validating it.
62
+ *
63
+ * This method verifies that the stored signature and message are still valid
64
+ * before returning them as an EIP4361AuthSignature object.
65
+ *
66
+ * @returns {Promise<EIP4361AuthSignature>} The validated authentication signature
67
+ * @throws {Error} If signature verification fails
68
+ */
21
69
  async getOrCreateAuthSignature() {
70
+ await generateAndVerifySiweMessage(this.existingSiweMessage, this.signature);
22
71
  const scheme = EIP4361_AUTH_METHOD;
23
72
  return {
24
73
  signature: this.signature,
@@ -1 +1 @@
1
- {"version":3,"file":"external-eip4361.js","sourceRoot":"","sources":["../../../../src/providers/eip4361/external-eip4361.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAInC,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C,MAAM,CAAC,MAAM,mCAAmC,GAC9C,6BAA6B,CAAC;AAEhC,MAAM,OAAO,+BAA+B;IAkBvB;IACD;IACC;IAnBZ,MAAM,CAAC,KAAK,CAAC,oBAAoB,CACtC,mBAA2B,EAC3B,SAAiB;QAEjB,aAAa;QACb,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,mBAAmB,CAAC,CAAC;QACzD,MAAM,WAAW,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;QACxC,kBAAkB;QAClB,MAAM,YAAY,GAAG,IAAI,+BAA+B,CACtD,WAAW,CAAC,cAAc,EAAE,EAC5B,WAAW,CAAC,OAAO,EACnB,SAAS,CACV,CAAC;QACF,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,YACmB,mBAA2B,EAC5B,OAAe,EACd,SAAiB;QAFjB,wBAAmB,GAAnB,mBAAmB,CAAQ;QAC5B,YAAO,GAAP,OAAO,CAAQ;QACd,cAAS,GAAT,SAAS,CAAQ;IACjC,CAAC;IAEG,KAAK,CAAC,wBAAwB;QACnC,MAAM,MAAM,GAAG,mBAAmB,CAAC;QACnC,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,mBAAmB;SACpC,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"external-eip4361.js","sourceRoot":"","sources":["../../../../src/providers/eip4361/external-eip4361.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAInC,OAAO,EAAE,mBAAmB,EAAwB,MAAM,QAAQ,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AAEtD,KAAK,UAAU,4BAA4B,CACzC,OAAe,EACf,SAAiB;IAEjB,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7C,wGAAwG;IACxG,MAAM,WAAW,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IACxC,MAAM,iBAAiB,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,yBAAyB,CAAC,CAAC;IAC3E,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK;QACb,2BAA2B;QAC3B,wFAAwF,CACzF,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,iBAAiB,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CACb,wFAAwF,CACzF,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,GAAG,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CACb,qDAAqD,WAAW,CAAC,QAAQ,uCAAuC,CACjH,CAAC;IACJ,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,+BAA+B;IAmCvB;IACD;IACC;IApCnB;;;;;;;OAOG;IACI,MAAM,CAAC,KAAK,CAAC,oBAAoB,CACtC,mBAA2B,EAC3B,SAAiB;QAEjB,MAAM,WAAW,GAAG,MAAM,4BAA4B,CACpD,mBAAmB,EACnB,SAAS,CACV,CAAC;QAEF,kBAAkB;QAClB,MAAM,YAAY,GAAG,IAAI,+BAA+B,CACtD,WAAW,CAAC,cAAc,EAAE,EAC5B,WAAW,CAAC,OAAO,EACnB,SAAS,CACV,CAAC;QACF,OAAO,YAAY,CAAC;IACtB,CAAC;IAED;;;;;;OAMG;IACH,YACmB,mBAA2B,EAC5B,OAAe,EACd,SAAiB;QAFjB,wBAAmB,GAAnB,mBAAmB,CAAQ;QAC5B,YAAO,GAAP,OAAO,CAAQ;QACd,cAAS,GAAT,SAAS,CAAQ;IACjC,CAAC;IAEJ;;;;;;;;OAQG;IACI,KAAK,CAAC,wBAAwB;QACnC,MAAM,4BAA4B,CAChC,IAAI,CAAC,mBAAmB,EACxB,IAAI,CAAC,SAAS,CACf,CAAC;QAEF,MAAM,MAAM,GAAG,mBAAmB,CAAC;QACnC,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,mBAAmB;SACpC,CAAC;IACJ,CAAC;CACF"}
@@ -1,2 +1,5 @@
1
+ export { EIP1271AuthSignature } from './eip1271/auth';
2
+ export * from './eip1271/eip1271';
3
+ export { EIP4361AuthSignature, USER_ADDRESS_PARAM_DEFAULT, } from './eip4361/auth';
1
4
  export * from './eip4361/eip4361';
2
5
  export * from './eip4361/external-eip4361';
@@ -1,3 +1,5 @@
1
+ export * from './eip1271/eip1271';
2
+ export { USER_ADDRESS_PARAM_DEFAULT, } from './eip4361/auth';
1
3
  export * from './eip4361/eip4361';
2
4
  export * from './eip4361/external-eip4361';
3
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/index.ts"],"names":[],"mappings":"AAEA,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAEL,0BAA0B,GAC3B,MAAM,gBAAgB,CAAC;AACxB,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC"}
@@ -1,8 +1,10 @@
1
+ import { z } from 'zod';
1
2
  import { AuthSignature } from './index';
2
- export declare class LocalStorage {
3
+ export declare class LocalStorage<T extends AuthSignature> {
3
4
  private storage;
4
- constructor();
5
- getAuthSignature(key: string): AuthSignature | null;
6
- setAuthSignature(key: string, authSignature: AuthSignature): void;
5
+ private signatureSchema;
6
+ constructor(signatureSchema: z.ZodSchema);
7
+ getAuthSignature(key: string): T | null;
8
+ setAuthSignature(key: string, authSignature: T): void;
7
9
  clear(key: string): void;
8
10
  }
@@ -1,4 +1,3 @@
1
- import { authSignatureSchema } from './index';
2
1
  class BrowserStorage {
3
2
  getItem(key) {
4
3
  return localStorage.getItem(key);
@@ -24,18 +23,20 @@ class NodeStorage {
24
23
  }
25
24
  export class LocalStorage {
26
25
  storage;
27
- constructor() {
26
+ signatureSchema;
27
+ constructor(signatureSchema) {
28
28
  this.storage =
29
29
  typeof localStorage === 'undefined'
30
30
  ? new NodeStorage()
31
31
  : new BrowserStorage();
32
+ this.signatureSchema = signatureSchema;
32
33
  }
33
34
  getAuthSignature(key) {
34
35
  const asJson = this.storage.getItem(key);
35
36
  if (!asJson) {
36
37
  return null;
37
38
  }
38
- return authSignatureSchema.parse(JSON.parse(asJson));
39
+ return this.signatureSchema.parse(JSON.parse(asJson));
39
40
  }
40
41
  setAuthSignature(key, authSignature) {
41
42
  const asJson = JSON.stringify(authSignature);
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAU7D,MAAM,cAAc;IACX,OAAO,CAAC,GAAW;QACxB,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;IAEM,OAAO,CAAC,GAAW,EAAE,KAAa;QACvC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;IAEM,UAAU,CAAC,GAAW;QAC3B,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,WAAW;IACP,OAAO,GAA2B,EAAE,CAAC;IAEtC,OAAO,CAAC,GAAW;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IACnC,CAAC;IAEM,OAAO,CAAC,GAAW,EAAE,KAAa;QACvC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC5B,CAAC;IAEM,UAAU,CAAC,GAAW;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,OAAO,YAAY;IACf,OAAO,CAAW;IAE1B;QACE,IAAI,CAAC,OAAO;YACV,OAAO,YAAY,KAAK,WAAW;gBACjC,CAAC,CAAC,IAAI,WAAW,EAAE;gBACnB,CAAC,CAAC,IAAI,cAAc,EAAE,CAAC;IAC7B,CAAC;IAEM,gBAAgB,CAAC,GAAW;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACvD,CAAC;IAEM,gBAAgB,CAAC,GAAW,EAAE,aAA4B;QAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IAEM,KAAK,CAAC,GAAW;QACtB,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;CACF"}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/storage.ts"],"names":[],"mappings":"AAYA,MAAM,cAAc;IACX,OAAO,CAAC,GAAW;QACxB,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;IAEM,OAAO,CAAC,GAAW,EAAE,KAAa;QACvC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;IAEM,UAAU,CAAC,GAAW;QAC3B,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,WAAW;IACP,OAAO,GAA2B,EAAE,CAAC;IAEtC,OAAO,CAAC,GAAW;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IACnC,CAAC;IAEM,OAAO,CAAC,GAAW,EAAE,KAAa;QACvC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC5B,CAAC;IAEM,UAAU,CAAC,GAAW;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,OAAO,YAAY;IACf,OAAO,CAAW;IAClB,eAAe,CAAc;IAErC,YAAY,eAA4B;QACtC,IAAI,CAAC,OAAO;YACV,OAAO,YAAY,KAAK,WAAW;gBACjC,CAAC,CAAC,IAAI,WAAW,EAAE;gBACnB,CAAC,CAAC,IAAI,cAAc,EAAE,CAAC;QAC3B,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;IACzC,CAAC;IAEM,gBAAgB,CAAC,GAAW;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACxD,CAAC;IAEM,gBAAgB,CAAC,GAAW,EAAE,aAAgB;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IAEM,KAAK,CAAC,GAAW;QACtB,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;CACF"}