From 05a2248944eeb2f4fcefa6e20a73e7dbabf14a5f Mon Sep 17 00:00:00 2001
From: Piotr Roslaniec
Date: Tue, 9 Jul 2024 15:56:28 +0200
Subject: [PATCH] feat!(auth): expose eip4361 auth provider in taco api
---
demos/taco-demo/src/App.tsx | 6 ++--
examples/taco/nextjs/package.json | 1 +
examples/taco/nextjs/src/hooks/useTaco.ts | 10 +++++--
examples/taco/nodejs/src/index.ts | 14 +++++-----
examples/taco/react/package.json | 1 +
examples/taco/react/src/hooks/useTaco.ts | 10 +++++--
examples/taco/react/tsconfig.build.json | 3 ++
examples/taco/webpack-5/package.json | 3 +-
examples/taco/webpack-5/src/index.ts | 4 ++-
examples/taco/webpack-5/tsconfig.json | 3 ++
packages/taco-auth/src/auth-provider.ts | 2 +-
packages/taco-auth/src/providers/eip4361.ts | 5 ++--
packages/taco/src/index.ts | 2 +-
packages/taco/src/taco.ts | 28 ++++---------------
packages/taco/test/conditions/context.test.ts | 24 ++++++++--------
packages/taco/test/taco.test.ts | 21 ++++----------
pnpm-lock.yaml | 9 ++++++
17 files changed, 74 insertions(+), 72 deletions(-)
diff --git a/demos/taco-demo/src/App.tsx b/demos/taco-demo/src/App.tsx
index 7fe6c9c39..2aa5f07a8 100644
--- a/demos/taco-demo/src/App.tsx
+++ b/demos/taco-demo/src/App.tsx
@@ -13,11 +13,11 @@ import { ethers } from 'ethers';
import React, { useEffect, useState } from 'react';
import { ConditionBuilder } from './ConditionBuilder';
-import { DEFAULT_DOMAIN, DEFAULT_RITUAL_ID } from './config';
import { Decrypt } from './Decrypt';
import { Encrypt } from './Encrypt';
-import { downloadData, getWebIrys, uploadData } from './irys';
import { Spinner } from './Spinner';
+import { DEFAULT_DOMAIN, DEFAULT_RITUAL_ID } from './config';
+import { downloadData, getWebIrys, uploadData } from './irys';
const chainIdForDomain = {
[domains.DEVNET]: 80002,
@@ -121,7 +121,7 @@ export default function App() {
Notice
In production (mainnet domain), your wallet address (encryptor) will also have
- to be allow-listed for this specific ritual. However, we have
+ to be allow-listed for this specific ritual. However, we have
publicly available testnet rituals
for use when developing your apps.
diff --git a/examples/taco/nextjs/package.json b/examples/taco/nextjs/package.json
index 61ab779a4..70efff2f4 100644
--- a/examples/taco/nextjs/package.json
+++ b/examples/taco/nextjs/package.json
@@ -13,6 +13,7 @@
"dependencies": {
"@nucypher/shared": "workspace:*",
"@nucypher/taco": "workspace:*",
+ "@nucypher/taco-auth": "workspace:*",
"@types/node": "20.11.30",
"@types/react": "18.2.48",
"@types/react-dom": "18.2.18",
diff --git a/examples/taco/nextjs/src/hooks/useTaco.ts b/examples/taco/nextjs/src/hooks/useTaco.ts
index 376a80a62..795b2b3a6 100644
--- a/examples/taco/nextjs/src/hooks/useTaco.ts
+++ b/examples/taco/nextjs/src/hooks/useTaco.ts
@@ -7,6 +7,7 @@ import {
initialize,
ThresholdMessageKit,
} from '@nucypher/taco';
+import { EIP4361AuthProvider } from '@nucypher/taco-auth';
import { ethers } from 'ethers';
import { useCallback, useEffect, useState } from 'react';
@@ -26,15 +27,18 @@ export default function useTaco({
}, []);
const decryptDataFromBytes = useCallback(
- async (encryptedBytes: Uint8Array, signer?: ethers.Signer) => {
- if (!isInit || !provider) return;
+ async (encryptedBytes: Uint8Array, signer: ethers.Signer) => {
+ if (!isInit || !provider) {
+ return;
+ }
const messageKit = ThresholdMessageKit.fromBytes(encryptedBytes);
+ const authProvider = new EIP4361AuthProvider(provider, signer);
return decrypt(
provider,
domain,
messageKit,
+ authProvider,
getPorterUri(domain),
- signer,
);
},
[isInit, provider, domain],
diff --git a/examples/taco/nodejs/src/index.ts b/examples/taco/nodejs/src/index.ts
index 5b17cd7cc..4db93ea87 100644
--- a/examples/taco/nodejs/src/index.ts
+++ b/examples/taco/nodejs/src/index.ts
@@ -1,8 +1,7 @@
import { format } from 'node:util';
import {
- conditions,
- decryptWithAuthProviders,
+ conditions, decrypt,
domains,
encrypt,
fromBytes,
@@ -12,7 +11,7 @@ import {
toBytes,
toHexString,
} from '@nucypher/taco';
-import { makeAuthProviders } from '@nucypher/taco-auth';
+import { EIP4361AuthProvider } from '@nucypher/taco-auth';
import * as dotenv from 'dotenv';
import { ethers } from 'ethers';
@@ -85,15 +84,16 @@ const decryptFromBytes = async (encryptedBytes: Uint8Array) => {
const messageKit = ThresholdMessageKit.fromBytes(encryptedBytes);
console.log('Decrypting message ...');
- const authProviders = makeAuthProviders(provider, consumerSigner, {
+ const siweParams = {
domain: 'localhost',
uri: 'http://localhost:3000',
- });
- return decryptWithAuthProviders(
+ };
+ const authProvider = new EIP4361AuthProvider(provider, consumerSigner, siweParams);
+ return decrypt(
provider,
domain,
messageKit,
- authProviders,
+ authProvider,
getPorterUri(domain),
);
};
diff --git a/examples/taco/react/package.json b/examples/taco/react/package.json
index 42213a78c..8c3aae51e 100644
--- a/examples/taco/react/package.json
+++ b/examples/taco/react/package.json
@@ -25,6 +25,7 @@
"dependencies": {
"@nucypher/shared": "workspace:*",
"@nucypher/taco": "workspace:*",
+ "@nucypher/taco-auth": "workspace:*",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
diff --git a/examples/taco/react/src/hooks/useTaco.ts b/examples/taco/react/src/hooks/useTaco.ts
index 376a80a62..795b2b3a6 100644
--- a/examples/taco/react/src/hooks/useTaco.ts
+++ b/examples/taco/react/src/hooks/useTaco.ts
@@ -7,6 +7,7 @@ import {
initialize,
ThresholdMessageKit,
} from '@nucypher/taco';
+import { EIP4361AuthProvider } from '@nucypher/taco-auth';
import { ethers } from 'ethers';
import { useCallback, useEffect, useState } from 'react';
@@ -26,15 +27,18 @@ export default function useTaco({
}, []);
const decryptDataFromBytes = useCallback(
- async (encryptedBytes: Uint8Array, signer?: ethers.Signer) => {
- if (!isInit || !provider) return;
+ async (encryptedBytes: Uint8Array, signer: ethers.Signer) => {
+ if (!isInit || !provider) {
+ return;
+ }
const messageKit = ThresholdMessageKit.fromBytes(encryptedBytes);
+ const authProvider = new EIP4361AuthProvider(provider, signer);
return decrypt(
provider,
domain,
messageKit,
+ authProvider,
getPorterUri(domain),
- signer,
);
},
[isInit, provider, domain],
diff --git a/examples/taco/react/tsconfig.build.json b/examples/taco/react/tsconfig.build.json
index 22ff2bd0b..beb822b78 100644
--- a/examples/taco/react/tsconfig.build.json
+++ b/examples/taco/react/tsconfig.build.json
@@ -9,6 +9,9 @@
"references": [
{
"path": "../../../packages/taco/tsconfig.es.json"
+ },
+ {
+ "path": "../../../packages/taco-auth/tsconfig.es.json"
}
]
}
diff --git a/examples/taco/webpack-5/package.json b/examples/taco/webpack-5/package.json
index 2a68fce2b..ed205e100 100644
--- a/examples/taco/webpack-5/package.json
+++ b/examples/taco/webpack-5/package.json
@@ -12,7 +12,8 @@
"type-check": "tsc"
},
"dependencies": {
- "@nucypher/taco": "workspace:*"
+ "@nucypher/taco": "workspace:*",
+ "@nucypher/taco-auth": "workspace:*"
},
"devDependencies": {
"copy-webpack-plugin": "^12.0.2",
diff --git a/examples/taco/webpack-5/src/index.ts b/examples/taco/webpack-5/src/index.ts
index 2cfd040d2..771cf5fa4 100644
--- a/examples/taco/webpack-5/src/index.ts
+++ b/examples/taco/webpack-5/src/index.ts
@@ -8,6 +8,7 @@ import {
initialize,
toBytes,
} from '@nucypher/taco';
+import { EIP4361AuthProvider } from '@nucypher/taco-auth';
import { ethers } from 'ethers';
import { hexlify } from 'ethers/lib/utils';
@@ -60,12 +61,13 @@ const runExample = async () => {
);
console.log('Decrypting message...');
+ const authProvider = new EIP4361AuthProvider(provider, signer);
const decryptedBytes = await decrypt(
provider,
domain,
messageKit,
+ authProvider,
getPorterUri(domain),
- signer,
);
const decryptedMessage = fromBytes(decryptedBytes);
console.log('Decrypted message:', decryptedMessage);
diff --git a/examples/taco/webpack-5/tsconfig.json b/examples/taco/webpack-5/tsconfig.json
index 8ee7f0a76..56863c42b 100644
--- a/examples/taco/webpack-5/tsconfig.json
+++ b/examples/taco/webpack-5/tsconfig.json
@@ -10,5 +10,8 @@
{
"path": "../../../packages/taco/tsconfig.es.json",
},
+ {
+ "path": "../../../packages/taco-auth/tsconfig.es.json",
+ }
],
}
diff --git a/packages/taco-auth/src/auth-provider.ts b/packages/taco-auth/src/auth-provider.ts
index 8f7d18578..18e83d5e6 100644
--- a/packages/taco-auth/src/auth-provider.ts
+++ b/packages/taco-auth/src/auth-provider.ts
@@ -24,7 +24,7 @@ export const USER_ADDRESS_PARAM_EIP712 = `:userAddress${EIP712_AUTH_METHOD}`;
export const USER_ADDRESS_PARAM_EIP4361 = `:userAddress${EIP4361_AUTH_METHOD}`;
export const AUTH_METHOD_FOR_PARAM: Record = {
- [USER_ADDRESS_PARAM_DEFAULT]: EIP712_AUTH_METHOD,
+ [USER_ADDRESS_PARAM_DEFAULT]: EIP4361_AUTH_METHOD,
[USER_ADDRESS_PARAM_EIP712]: EIP712_AUTH_METHOD,
[USER_ADDRESS_PARAM_EIP4361]: EIP4361_AUTH_METHOD,
};
diff --git a/packages/taco-auth/src/providers/eip4361.ts b/packages/taco-auth/src/providers/eip4361.ts
index 9e06fcce5..5f95e30ab 100644
--- a/packages/taco-auth/src/providers/eip4361.ts
+++ b/packages/taco-auth/src/providers/eip4361.ts
@@ -37,10 +37,9 @@ export class EIP4361AuthProvider {
private getDefaultParameters() {
if (typeof window !== 'undefined') {
// If we are in a browser environment, we can get the domain and uri from the window object
- const maybeOrigin = window?.location?.origin;
return {
- domain: maybeOrigin.split('//')[1].split('.')[0],
- uri: maybeOrigin,
+ domain: window.location?.host,
+ uri: window.location?.origin,
};
}
// If not, we have no choice but to throw an error
diff --git a/packages/taco/src/index.ts b/packages/taco/src/index.ts
index 26b93c60e..d737d6ed6 100644
--- a/packages/taco/src/index.ts
+++ b/packages/taco/src/index.ts
@@ -11,4 +11,4 @@ export {
export * as conditions from './conditions';
// Expose registerEncrypters from taco API (#324)
-export { decrypt, decryptWithAuthProviders, encrypt, encryptWithPublicKey, isAuthorized } from './taco';
+export { decrypt, encrypt, encryptWithPublicKey, isAuthorized } from './taco';
diff --git a/packages/taco/src/taco.ts b/packages/taco/src/taco.ts
index 7ef2e7cba..5e59de4de 100644
--- a/packages/taco/src/taco.ts
+++ b/packages/taco/src/taco.ts
@@ -13,7 +13,7 @@ import {
GlobalAllowListAgent,
toBytes,
} from '@nucypher/shared';
-import { AuthProviders, makeAuthProviders } from '@nucypher/taco-auth';
+import { AuthProviders, EIP4361_AUTH_METHOD, EIP4361AuthProvider } from '@nucypher/taco-auth';
import { ethers } from 'ethers';
import { keccak256 } from 'ethers/lib/utils';
@@ -125,9 +125,9 @@ export const encryptWithPublicKey = async (
* @param {Domain} domain - Represents the logical network in which the decryption will be performed.
* Must match the `ritualId`.
* @param {ThresholdMessageKit} messageKit - The kit containing the message to be decrypted
+ * @param authProvider
* @param {string} [porterUri] - The URI for the Porter service. If not provided, a value will be obtained
* from the Domain
- * @param {ethers.Signer} [signer] - An optional signer for the decryption
* @param {Record} [customParameters] - Optional custom parameters that may be required
* depending on the condition used
*
@@ -140,26 +140,7 @@ export const decrypt = async (
provider: ethers.providers.Provider,
domain: Domain,
messageKit: ThresholdMessageKit,
- porterUri?: string,
- signer?: ethers.Signer,
- customParameters?: Record,
-): Promise => {
- const authProviders = makeAuthProviders(provider, signer);
- return decryptWithAuthProviders(
- provider,
- domain,
- messageKit,
- authProviders,
- porterUri,
- customParameters,
- );
-};
-
-export const decryptWithAuthProviders = async (
- provider: ethers.providers.Provider,
- domain: Domain,
- messageKit: ThresholdMessageKit,
- authProviders?: AuthProviders,
+ authProvider: EIP4361AuthProvider,
porterUri?: string,
customParameters?: Record,
): Promise => {
@@ -173,6 +154,9 @@ export const decryptWithAuthProviders = async (
messageKit.acp.publicKey,
);
const ritual = await DkgClient.getActiveRitual(provider, domain, ritualId);
+ const authProviders: AuthProviders = {
+ [EIP4361_AUTH_METHOD]: authProvider,
+ };
return retrieveAndDecrypt(
provider,
domain,
diff --git a/packages/taco/test/conditions/context.test.ts b/packages/taco/test/conditions/context.test.ts
index 1a42ad330..5120a8685 100644
--- a/packages/taco/test/conditions/context.test.ts
+++ b/packages/taco/test/conditions/context.test.ts
@@ -405,8 +405,18 @@ describe('No authentication provider', () => {
expect(eip712Spy).toHaveBeenCalledOnce();
}
- it('supports default auth method (eip712)', async () => {
- await testEIP712AuthMethod(USER_ADDRESS_PARAM_DEFAULT);
+ async function testEIP4361AuthMethod(authMethod: string) {
+ const eip4361Spy = vi.spyOn(
+ EIP4361AuthProvider.prototype,
+ 'getOrCreateAuthSignature',
+ );
+ const authSignature = await makeAuthSignature(authMethod);
+ await testEIP4361AuthSignature(authSignature);
+ expect(eip4361Spy).toHaveBeenCalledOnce();
+ }
+
+ it('supports default auth method (eip4361)', async () => {
+ await testEIP4361AuthMethod(USER_ADDRESS_PARAM_DEFAULT);
});
it('supports eip712', async () => {
@@ -414,15 +424,7 @@ describe('No authentication provider', () => {
});
it('supports eip4361', async () => {
- const eip4361Spy = vi.spyOn(
- EIP4361AuthProvider.prototype,
- 'getOrCreateAuthSignature',
- );
-
- const authSignature = await makeAuthSignature(USER_ADDRESS_PARAM_EIP4361);
- await testEIP4361AuthSignature(authSignature);
-
- expect(eip4361Spy).toHaveBeenCalledOnce();
+ await testEIP4361AuthMethod(USER_ADDRESS_PARAM_EIP4361);
});
it('supports reusing external eip4361', async () => {
diff --git a/packages/taco/test/taco.test.ts b/packages/taco/test/taco.test.ts
index c4a738345..af3a06c2c 100644
--- a/packages/taco/test/taco.test.ts
+++ b/packages/taco/test/taco.test.ts
@@ -16,7 +16,7 @@ import {
mockTacoDecrypt,
TEST_CHAIN_ID, TEST_SIWE_PARAMS,
} from '@nucypher/test-utils';
-import { beforeAll, describe, expect, it, vi } from 'vitest';
+import { beforeAll, describe, expect, it } from 'vitest';
import * as taco from '../src';
import { conditions, domains, toBytes } from '../src';
@@ -83,31 +83,20 @@ describe('taco', () => {
);
const getRitualSpy = mockGetActiveRitual(mockedDkgRitual);
- const authProviders = tacoAuth.makeAuthProviders(provider, signer,TEST_SIWE_PARAMS);
- const decryptedMessage1 = await taco.decryptWithAuthProviders(
+ const authProvider = new tacoAuth.EIP4361AuthProvider(provider, signer, TEST_SIWE_PARAMS);
+ const decryptedMessage = await taco.decrypt(
provider,
domains.DEVNET,
messageKit,
- authProviders,
+ authProvider,
fakePorterUri,
);
- expect(decryptedMessage1).toEqual(toBytes(message));
+ expect(decryptedMessage).toEqual(toBytes(message));
expect(getParticipantsSpy).toHaveBeenCalled();
expect(sessionKeySpy).toHaveBeenCalled();
expect(getRitualIdFromPublicKey).toHaveBeenCalled();
expect(getRitualSpy).toHaveBeenCalled();
expect(decryptSpy).toHaveBeenCalled();
-
- const makeAuthProvidersSpy = vi.spyOn(tacoAuth, 'makeAuthProviders').mockImplementation(() => authProviders);
- const decryptedMessage2 = await taco.decrypt(
- provider,
- domains.DEVNET,
- messageKit,
- fakePorterUri,
- signer,
- );
- expect(makeAuthProvidersSpy).toHaveBeenCalled();
- expect(decryptedMessage2).toEqual(toBytes(message));
});
it('exposes requested parameters', async () => {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index ff5e622a9..b0bb7ddbf 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -371,6 +371,9 @@ importers:
'@nucypher/taco':
specifier: workspace:*
version: link:../../../packages/taco
+ '@nucypher/taco-auth':
+ specifier: workspace:*
+ version: link:../../../packages/taco-auth
'@types/node':
specifier: 20.11.30
version: 20.11.30
@@ -425,6 +428,9 @@ importers:
'@nucypher/taco':
specifier: workspace:*
version: link:../../../packages/taco
+ '@nucypher/taco-auth':
+ specifier: workspace:*
+ version: link:../../../packages/taco-auth
ethers:
specifier: ^5.7.2
version: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10)
@@ -453,6 +459,9 @@ importers:
'@nucypher/taco':
specifier: workspace:*
version: link:../../../packages/taco
+ '@nucypher/taco-auth':
+ specifier: workspace:*
+ version: link:../../../packages/taco-auth
ethers:
specifier: ^5.7.2
version: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10)