Skip to content
This repository has been archived by the owner on Aug 1, 2024. It is now read-only.

Commit

Permalink
feat!(auth): expose eip4361 auth provider in taco api
Browse files Browse the repository at this point in the history
  • Loading branch information
piotr-roslaniec committed Jul 9, 2024
1 parent 9ce1a99 commit 05a2248
Show file tree
Hide file tree
Showing 17 changed files with 74 additions and 72 deletions.
6 changes: 3 additions & 3 deletions demos/taco-demo/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -121,7 +121,7 @@ export default function App() {
<h2>Notice</h2>
<p>
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
<a href={'https://docs.threshold.network/app-development/threshold-access-control-tac/integration-guide/get-started-with-tac#testnet-configuration'}>publicly available testnet rituals</a>
for use when developing your apps.
</p>
Expand Down
1 change: 1 addition & 0 deletions examples/taco/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
10 changes: 7 additions & 3 deletions examples/taco/nextjs/src/hooks/useTaco.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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],
Expand Down
14 changes: 7 additions & 7 deletions examples/taco/nodejs/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { format } from 'node:util';

import {
conditions,
decryptWithAuthProviders,
conditions, decrypt,
domains,
encrypt,
fromBytes,
Expand All @@ -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';

Expand Down Expand Up @@ -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),
);
};
Expand Down
1 change: 1 addition & 0 deletions examples/taco/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"dependencies": {
"@nucypher/shared": "workspace:*",
"@nucypher/taco": "workspace:*",
"@nucypher/taco-auth": "workspace:*",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
10 changes: 7 additions & 3 deletions examples/taco/react/src/hooks/useTaco.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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],
Expand Down
3 changes: 3 additions & 0 deletions examples/taco/react/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
"references": [
{
"path": "../../../packages/taco/tsconfig.es.json"
},
{
"path": "../../../packages/taco-auth/tsconfig.es.json"
}
]
}
3 changes: 2 additions & 1 deletion examples/taco/webpack-5/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 3 additions & 1 deletion examples/taco/webpack-5/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions examples/taco/webpack-5/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@
{
"path": "../../../packages/taco/tsconfig.es.json",
},
{
"path": "../../../packages/taco-auth/tsconfig.es.json",
}
],
}
2 changes: 1 addition & 1 deletion packages/taco-auth/src/auth-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, string> = {
[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,
};
5 changes: 2 additions & 3 deletions packages/taco-auth/src/providers/eip4361.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion packages/taco/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
28 changes: 6 additions & 22 deletions packages/taco/src/taco.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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<string, CustomContextParam>} [customParameters] - Optional custom parameters that may be required
* depending on the condition used
*
Expand All @@ -140,26 +140,7 @@ export const decrypt = async (
provider: ethers.providers.Provider,
domain: Domain,
messageKit: ThresholdMessageKit,
porterUri?: string,
signer?: ethers.Signer,
customParameters?: Record<string, CustomContextParam>,
): Promise<Uint8Array> => {
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<string, CustomContextParam>,
): Promise<Uint8Array> => {
Expand All @@ -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,
Expand Down
24 changes: 13 additions & 11 deletions packages/taco/test/conditions/context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,24 +405,26 @@ 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 () => {
await testEIP712AuthMethod(USER_ADDRESS_PARAM_EIP712);
});

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 () => {
Expand Down
21 changes: 5 additions & 16 deletions packages/taco/test/taco.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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 () => {
Expand Down
9 changes: 9 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 05a2248

Please sign in to comment.