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

Refactor packages APIs #301

Merged
merged 24 commits into from
Oct 6, 2023

Conversation

piotr-roslaniec
Copy link
Contributor

@piotr-roslaniec piotr-roslaniec commented Sep 22, 2023

Type of PR:

  • Refactor
  • Other

Required reviews:

  • 2

Issues fixed/closed:

What this does:

  • Continues refactoring of monorepo packages
  • Configures tests to use inlined WASM when using @nucypher/nucypher-core
  • Refactors from character-based to functional API
    • In the taco package
    • In the pre package Not a priority
  • Updates taco for compatibility with dkg-alpha-13, including examples
  • Adds a demos/taco-demo

Notes for reviewers:

@codecov-commenter
Copy link

codecov-commenter commented Sep 22, 2023

Codecov Report

Merging #301 (0a13562) into monorepo (15ea563) will increase coverage by 22.58%.
Report is 2 commits behind head on monorepo.
The diff coverage is 95.08%.

@@              Coverage Diff              @@
##           monorepo     #301       +/-   ##
=============================================
+ Coverage     65.67%   88.25%   +22.58%     
=============================================
  Files            48       33       -15     
  Lines          5223     2409     -2814     
  Branches         28      205      +177     
=============================================
- Hits           3430     2126     -1304     
+ Misses         1787      254     -1533     
- Partials          6       29       +23     
Files Coverage Δ
packages/pre/src/characters/alice.ts 87.66% <100.00%> (ø)
packages/pre/src/characters/bob.ts 85.61% <100.00%> (ø)
packages/pre/src/characters/index.ts 100.00% <ø> (ø)
packages/pre/src/cohort.ts 89.28% <100.00%> (ø)
packages/pre/src/index.ts 100.00% <100.00%> (ø)
packages/pre/src/keyring.ts 93.67% <100.00%> (ø)
packages/pre/src/kits/index.ts 100.00% <ø> (ø)
packages/pre/src/kits/message.ts 91.25% <100.00%> (ø)
packages/pre/src/kits/retrieval.ts 77.27% <100.00%> (ø)
packages/taco/src/conditions/base/contract.ts 95.74% <ø> (ø)
... and 23 more

... and 14 files with indirect coverage changes

Copy link
Member

@cygnusv cygnusv left a comment

Choose a reason for hiding this comment

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

First pass. Looking good!

Comment on lines +1 to +8
import {
conditions,
decrypt,
encrypt,
getPorterUri,
initialize,
ThresholdMessageKit,
} from '@nucypher/taco';
Copy link
Member

Choose a reason for hiding this comment

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

Look how shiny! 🤩

Copy link
Member

Choose a reason for hiding this comment

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

It does look very clean 🎸

examples/README.md Outdated Show resolved Hide resolved
examples/taco/nextjs/src/app/page.tsx Show resolved Hide resolved

const privateKey = process.env.PRIVATE_KEY;
if (!privateKey) {
throw new Error('PRIVATE_KEY is not set.');
Copy link
Member

Choose a reason for hiding this comment

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

We have a hardcoded example key for Enrico in nucypher. See https://github.com/nucypher/nucypher/blob/4b978025a262f240a9afb9869257c070a33d767d/tests/constants.py#L88

Maybe we can use this here as a fallback?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On one hand, it makes sense - This Enrico is already configured on testnet (allow-listed and so on) but on the other hand, I'm not sure what happens when a number of users start testing their apps with this default character.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think we have much of a choice for tapir 🤔 , unless:

  1. we make ritual initiation public (for say tapir)
  2. grant initiator roles to those who ask

only specific Enricos would be allowed (global allow list) to encrypt for rituals.

If neither 1 or 2 are feasible, at the very least we can probably provide more than one test authorized Enrico account private key.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Decided to not pursue this change in the PR, tracking it here: #313

);

console.log('Decrypting message...');
const porterUri = getPorterUri('lynx'); // Test network
Copy link
Member

@cygnusv cygnusv Oct 5, 2023

Choose a reason for hiding this comment

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

How about we create some constants somewhere like TacoNetwork.DEV_TESTNET = 'lynx' and TacoNetwork.TESTNET = 'tapir', and we reduce a bit the cognitive load for adopters? After all, how necessary is that adopters know that the testnet is called lynx/tapir?

Thoughts? @piotr-roslaniec @KPrasch @derekpierre

Copy link
Member

@KPrasch KPrasch Oct 5, 2023

Choose a reason for hiding this comment

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

It's another level of abstraction above domains which at this level of public exposure makes sense to me! 👍🏻

I suggest that we adopt the nucypher/nucypher convention to call these "domains" instead of "networks" for accuracy (although imperfect since it's another layer):

TacoDomain.DEV; TacoDomain.TEST

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with both suggestions, tracking it in #311

Copy link
Member

Choose a reason for hiding this comment

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

Agreed 👍

examples/taco/webpack-5/src/index.html Outdated Show resolved Hide resolved
@@ -1,1375 +1,1423 @@
[
Copy link
Member

Choose a reason for hiding this comment

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

Opened #310 to use our NPM package instead of manually tracking here. The NPM package probably needs updating, though (cc @manumonti)

Copy link
Member

Choose a reason for hiding this comment

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

Nice - this thought crossed my mind as well.

@@ -13,7 +13,7 @@ const POLYGON: Contracts = {

const MUMBAI: Contracts = {
SUBSCRIPTION_MANAGER: '0xb9015d7b35ce7c81dde38ef7136baa3b1044f313',
COORDINATOR: '0x0f019Ade1D34399D946CF2f161386362655Dd1A4',
COORDINATOR: '0x8E49989F9D3aD89c8ab0de21FbA2E00C67ca872F',
Copy link
Member

Choose a reason for hiding this comment

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

Opened #310. The bulk of this module should be externalized to the NPM package. See also
nucypher/nucypher-contracts#124 for on-going discussion

Copy link
Member

@KPrasch KPrasch left a comment

Choose a reason for hiding this comment

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

It's so refreshing to see the demos so buttoned up and organized. 🤠

Comment on lines +5 to +7
- [`nucypher-ts-demo`](https://github.com/nucypher/nucypher-ts-demo) - A demo of PRE in the `nucypher-ts` library.
- [`tdec-sandbox`](https://github.com/nucypher/tdec-sandbox) - A demo of tDec in the `nucypher-ts` library.
- [`tdec-nft-example`](https://github.com/nucypher/tdec-nft-example) - A demo of tDec in the `nucypher-ts` library.
Copy link
Member

Choose a reason for hiding this comment

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

In the spirit of the monorepo, shall we also internalize these demos to this repo?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Internalizing nucypher-ts-demo will require releasing @nucypher/pre, which I think we should postpone. tdec-sandbox and tdec-nft-example will be deprecated (archived) and replaced by existing demos.

Copy link
Member

Choose a reason for hiding this comment

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

I also generally agree with the division of examples/demos mentioned above 👍🏻

Copy link
Member

Choose a reason for hiding this comment

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

tdec-sandbox and tdec-nft-example will be deprecated (archived) and replaced by existing demos.

^ If we are going to deprecate/archive these, should we remove these in the readme then?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will remove them from the README.md when we have a working alternative.

Copy link
Member

Choose a reason for hiding this comment

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

These things are easy to forget. If you are going to leave them for now, I'd recommend filing an issue and setting the appropriate project on it, so that it can be followed up on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tracked in #308

Comment on lines +18 to +21
### Polygon

`@nucypher/taco` is in an early release. We recommend **not** using it in
production _just yet_.
Copy link
Member

Choose a reason for hiding this comment

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

Do we need this for a demo readme?

await switchNetwork(Mumbai.chainId);

const provider = new ethers.providers.Web3Provider(window.ethereum);
const ritualId = 2; // Replace with your own ritual ID
Copy link
Member

@derekpierre derekpierre Oct 5, 2023

Choose a reason for hiding this comment

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

Is it possible to make this some sort of UI input, or browser var or some variable that users can easily set somewhere eg. some kind of .env file equivalent for local scripts? Even if localized to a specific file.

Whatever process for updating this number should end up in the readme/demo instructions.

Comment on lines +18 to +21
### Polygon

`@nucypher/taco` is in an early release. We recommend **not** using it in
production _just yet_.
Copy link
Member

Choose a reason for hiding this comment

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

Same question as in the other demo.

enabled,
}: Props) => {
const { library } = useEthers();
const goerliNFTAddress = '0x932Ca55B9Ef0b3094E8Fa82435b3b4c50d713043'; // https://goerli-nfts.vercel.app/
Copy link
Member

@derekpierre derekpierre Oct 5, 2023

Choose a reason for hiding this comment

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

Tapir is going to use sepolia (lynx will still use goerli) - so we'll need a new NFT address on sepolia.

They both will still use Mumbai, so if using an NFT on mumbai is simpler then that works too.

(cc @KPrasch )

Copy link
Member

@KPrasch KPrasch Oct 5, 2023

Choose a reason for hiding this comment

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

I guess we can keep this one around for use with Lynx, but yeah a new NFT contract on Sepolia will be needed, or as @derekpierre mentioned, just switch to a mumbai condition.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will update the demos when we release TACo on Sepolia. I always have to test them in cases like this anyway.

Comment on lines +89 to +93
const messageKit = await encrypt(provider, message, hasPositiveBalance, ritualId, signer);

console.log('Decrypting message...');
const porterUri = getPorterUri('lynx'); // Test network
const decryptedMessage = await decrypt(provider, messageKit, signer, porterUri);
Copy link
Member

Choose a reason for hiding this comment

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

These API calls look great!

value: 0,
},
});
const ritualId = 2; // Replace with your own ritual ID
Copy link
Member

Choose a reason for hiding this comment

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

Similar question about making this some sort of UI input/variable

packages/pre/src/policy.ts Show resolved Hide resolved
@@ -1,1375 +1,1423 @@
[
Copy link
Member

Choose a reason for hiding this comment

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

Nice - this thought crossed my mind as well.

@@ -11,7 +11,9 @@ export const rpcConditionSchema = z.object({
conditionType: z.literal(RpcConditionType).default(RpcConditionType),
chain: createUnionSchema(SUPPORTED_CHAIN_IDS),
method: z.enum(['eth_getBalance', 'balanceOf']),
parameters: z.array(EthAddressOrUserAddressSchema),
parameters: z.array(
z.union([EthAddressOrUserAddressSchema, z.string(), z.number()]),
Copy link
Member

Choose a reason for hiding this comment

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

Why not just EthAddressOrUserAddressSchema? Why also number or string?

PS. love how that typing reads.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The second parameter to eth_getBalance is blockNumer, which is a string (as per JSON RPC schema). I thought that accepting a number here would be more intuitive. Does that make sense? Or should we expose strict interfaces (lifted straight from JSON RPC)?

Copy link
Member

@derekpierre derekpierre Oct 5, 2023

Choose a reason for hiding this comment

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

Oh right I got you.

But then we ideally want something like:

parameters = (EthAddressOrUserAddressSchema) OR (EthAddressOrUserAddressSchema, Union[string, int]])

So something like the following then (my zod is bad)?

z.array(
     z.union([
           EthAddressOrUserAddressSchema,
           z.array(
                EthAddressOrUserAddressSchema,
                z.union([
                     z.string(),
                     z.number()]
               ])
          )
   ])
)

If the above is the simplest way (perhaps not), might be cleaner to define a custom schema type somewhere else, similar to how we did EthAddressOrUserAddressSchema.

We should test this if we aren't already.

authSigner,
);

const isAuthorized = DkgCoordinatorAgent.isEncryptionAuthorized(
Copy link
Member

Choose a reason for hiding this comment

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

I think this check should be optional, and not done by default.

In some/most cases it is ok for Enrico to encrypt before being authorized. Authorization can be granted after encryption and the authorization check only really applies at decryption time (this was a prior question from BqEth).

I get the notion of being proactive about authorization before encryption, but they are different in their timing.

(cc @cygnusv , @KPrasch ).

Copy link
Member

Choose a reason for hiding this comment

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

Indeed, it's use-case specific, ritual-specific, and may actually be performed by different actors or user stories altogether.

Copy link
Member

@cygnusv cygnusv left a comment

Choose a reason for hiding this comment

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

I reviewed code and ran the demo locally. Worked like a charm. Awesome work, Piotr! We're almost there

@piotr-roslaniec piotr-roslaniec merged commit 60eacdb into nucypher:monorepo Oct 6, 2023
1 check passed
@piotr-roslaniec piotr-roslaniec deleted the refactor-packages branch October 6, 2023 12:12
parameters: z.union([
z.array(EthAddressOrUserAddressSchema).length(1),
// Using tuple here because ordering matters
z.tuple([EthAddressOrUserAddressSchema, z.union([z.string(), z.number()])]),
Copy link
Member

Choose a reason for hiding this comment

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

Great - 🚀

@@ -34,4 +35,52 @@ describe('validation', () => {
},
});
});

describe('parameters', () => {
Copy link
Member

Choose a reason for hiding this comment

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

Love the testing!

This was referenced Oct 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Completed
Development

Successfully merging this pull request may close these issues.

7 participants