Skip to content

Commit

Permalink
publish @penumbra-zone/protobuf (#1016)
Browse files Browse the repository at this point in the history
  • Loading branch information
turbocrime authored May 2, 2024
1 parent 499c0e5 commit 6fb898a
Show file tree
Hide file tree
Showing 16 changed files with 204 additions and 104 deletions.
6 changes: 6 additions & 0 deletions .changeset/tender-mayflies-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@penumbra-zone/protobuf': major
'@penumbra-zone/types': major
---

initial release of `@penumbra-zone/protobuf` package containing `typeRegistry`. same removed from `@penumbra-zone/types`
1 change: 1 addition & 0 deletions apps/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"devDependencies": {
"@penumbra-zone/keys": "workspace:*",
"@penumbra-zone/polyfills": "workspace:*",
"@penumbra-zone/protobuf": "workspace:*",
"@radix-ui/react-icons": "^1.3.0",
"@types/firefox-webext-browser": "^120.0.3",
"@types/lodash": "^4.17.0",
Expand Down
4 changes: 2 additions & 2 deletions apps/extension/src/clients.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { ViewService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/
import { createPromiseClient } from '@connectrpc/connect';
import { createChannelTransport } from '@penumbra-zone/transport-dom/create';
import { CRSessionClient } from '@penumbra-zone/transport-chrome/session-client';
import { transportOptions } from '@penumbra-zone/types/registry';
import { jsonOptions } from '@penumbra-zone/protobuf';

const port = CRSessionClient.init(PRAX);

const extensionPageTransport = createChannelTransport({
jsonOptions,
getPort: () => Promise.resolve(port),
...transportOptions,
});

export const viewClient = createPromiseClient(ViewService, extensionPageTransport);
9 changes: 4 additions & 5 deletions apps/extension/src/service-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { ConnectRouter, createContextValues, PromiseClient } from '@connectrpc/c
import { CRSessionManager } from '@penumbra-zone/transport-chrome/session-manager';
import { createDirectClient } from '@penumbra-zone/transport-dom/direct';
import { connectChannelAdapter } from '@penumbra-zone/transport-dom/adapter';
import { transportOptions } from '@penumbra-zone/types/registry';
import { jsonOptions } from '@penumbra-zone/protobuf';

// context
import { CustodyService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/custody/v1/custody_connect';
Expand Down Expand Up @@ -107,8 +107,7 @@ const getServiceHandler = async () => {
let custodyClient: PromiseClient<typeof CustodyService> | undefined;
let stakingClient: PromiseClient<typeof StakingService> | undefined;
return connectChannelAdapter({
// jsonOptions contains typeRegistry providing ser/de
jsonOptions: transportOptions.jsonOptions,
jsonOptions,

/** @see https://connectrpc.com/docs/node/implementing-services */
routes: (router: ConnectRouter) =>
Expand All @@ -119,8 +118,8 @@ const getServiceHandler = async () => {
const contextValues = req.contextValues ?? createContextValues();

// dynamically initialize clients, or reuse if already available
custodyClient ??= createDirectClient(CustodyService, handler, transportOptions);
stakingClient ??= createDirectClient(StakingService, handler, transportOptions);
custodyClient ??= createDirectClient(CustodyService, handler, { jsonOptions });
stakingClient ??= createDirectClient(StakingService, handler, { jsonOptions });

contextValues.set(custodyCtx, custodyClient);
contextValues.set(stakingClientCtx, stakingClient);
Expand Down
4 changes: 2 additions & 2 deletions packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
}
},
"dependencies": {
"@penumbra-zone/transport-dom": "workspace:*",
"@penumbra-zone/types": "workspace:*"
"@penumbra-zone/protobuf": "workspace:*",
"@penumbra-zone/transport-dom": "workspace:*"
},
"devDependencies": {
"@bufbuild/protobuf": "^1.9.0",
Expand Down
5 changes: 2 additions & 3 deletions packages/client/src/prax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { Transport } from '@connectrpc/connect';
import { createPromiseClient } from '@connectrpc/connect';
import { createChannelTransport } from '@penumbra-zone/transport-dom/create';
import { PenumbraSymbol } from './global';
import { jsonOptions } from '@penumbra-zone/types/registry';
import { jsonOptions } from '@penumbra-zone/protobuf';

const prax_id = 'lkpmkhpnhknhmibgnmmhdhgdilepfghe';
const prax_origin = `chrome-extension://${prax_id}`;
Expand Down Expand Up @@ -86,9 +86,8 @@ export const throwIfPraxNotInstalled = async () => {
let praxTransport: Transport | undefined;
export const createPraxClient = <T extends ServiceType>(serviceType: T) => {
praxTransport ??= createChannelTransport({
defaultTimeoutMs: 10000,
getPort: getPraxPort,
jsonOptions,
getPort: getPraxPort,
});
return createPromiseClient(serviceType, praxTransport);
};
8 changes: 0 additions & 8 deletions packages/constants/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,5 @@
"types": "./dist/index.d.ts"
}
}
},
"devDependencies": {
"@buf/penumbra-zone_penumbra.bufbuild_es": "1.9.0-20240429125510-24b08e70bbc2.1",
"@bufbuild/protobuf": "^1.9.0"
},
"peerDependencies": {
"@buf/penumbra-zone_penumbra.bufbuild_es": "1.9.0-20240429125510-24b08e70bbc2.1",
"@bufbuild/protobuf": "^1.9.0"
}
}
8 changes: 8 additions & 0 deletions packages/protobuf/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
root: true,
extends: ['custom'],
parserOptions: {
project: true,
tsconfigRootDir: __dirname,
},
};
35 changes: 35 additions & 0 deletions packages/protobuf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# `@penumbra-zone/protobuf`

This package exports a `typeRegistry` (and inclusive `jsonOptions`) for use with
`@bufbuild` and `@connectrpc` tooling, particularly
`@penumbra-zone/transport-dom`.

All message types necessary for a Connect `Transport` to serialize/deserialize
communication with Prax or any other Penumbra extension are included.

## If you simply need a Penumbra extension client

You're looking for `@penumbra-zone/client`, which handles this process for you
and also performs some basic safety checks.

This package is provided for those who are interested in lower-level work or
more detailed configuration.

### Simple example

```ts
import { jsonOptions } from '@penumbra-zone/protobuf';

import { createChannelTransport } from '@penumbra-zone/transport-dom';
import type { ServiceType } from '@bufbuild/protobuf';

// unsafely get first available provider
const getPort = () => Object.values(window[Symbol.for('penumbra')])[0].connect();

// establish transport
const transport = createChannelTransport({ jsonOptions, getPort });

// function to create client
export const createPenumbraClient = (serviceType: ServiceType) =>
createPromiseClient(serviceType, transport);
```
42 changes: 42 additions & 0 deletions packages/protobuf/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "@penumbra-zone/protobuf",
"version": "0.0.0",
"license": "(MIT OR Apache-2.0)",
"description": "Exports a `@bufbuild/protobuf` type registry with all message types necessary to communicate with a Penumbra extension",
"type": "module",
"scripts": {
"build": "tsc --build",
"clean": "rm -rfv dist",
"lint": "eslint src",
"prepack": "pnpm clean && pnpm build"
},
"exports": {
".": "./src/registry.ts"
},
"publishConfig": {
"exports": {
".": {
"import": "./dist/registry.js",
"types": "./dist/registry.d.ts"
}
}
},
"bundleDependencies": [
"@buf/cosmos_ibc.bufbuild_es",
"@buf/cosmos_ibc.connectrpc_es",
"@buf/penumbra-zone_penumbra.bufbuild_es",
"@buf/penumbra-zone_penumbra.connectrpc_es"
],
"devDependencies": {
"@bufbuild/protobuf": "^1.9.0",
"@connectrpc/connect": "^1.4.0"
},
"peerDependencies": {
"@buf/cosmos_ibc.bufbuild_es": "1.9.0-20240327103030-e2006674271c.1",
"@buf/cosmos_ibc.connectrpc_es": "1.4.0-20240327103030-e2006674271c.2",
"@buf/penumbra-zone_penumbra.bufbuild_es": "1.9.0-20240429125510-24b08e70bbc2.1",
"@buf/penumbra-zone_penumbra.connectrpc_es": "1.4.0-20240429125510-24b08e70bbc2.2",
"@bufbuild/protobuf": "^1.9.0",
"@connectrpc/connect": "^1.4.0"
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import { Query as IbcClientService } from '@buf/cosmos_ibc.connectrpc_es/ibc/core/client/v1/query_connect';
import { IMessageTypeRegistry, createRegistry } from '@bufbuild/protobuf';

import { CustodyService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/custody/v1/custody_connect';
import { ViewService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/view/v1/view_connect';

import { ClientState } from '@buf/cosmos_ibc.bufbuild_es/ibc/lightclients/tendermint/v1/tendermint_pb';

import { TendermintProxyService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/util/tendermint_proxy/v1/tendermint_proxy_connect';

import { Query as IbcChannelService } from '@buf/cosmos_ibc.connectrpc_es/ibc/core/channel/v1/query_connect';
import { Query as IbcClientService } from '@buf/cosmos_ibc.connectrpc_es/ibc/core/client/v1/query_connect';
import { Query as IbcConnectionService } from '@buf/cosmos_ibc.connectrpc_es/ibc/core/connection/v1/query_connect';

import { QueryService as AppService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/core/app/v1/app_connect';
import { QueryService as CompactBlockService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/core/component/compact_block/v1/compact_block_connect';
import {
Expand All @@ -11,30 +21,27 @@ import { QueryService as GovernanceService } from '@buf/penumbra-zone_penumbra.c
import { QueryService as SctService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/core/component/sct/v1/sct_connect';
import { QueryService as ShieldedPoolService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/core/component/shielded_pool/v1/shielded_pool_connect';
import { QueryService as StakeService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/core/component/stake/v1/stake_connect';
import { CustodyService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/custody/v1/custody_connect';
import { TendermintProxyService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/util/tendermint_proxy/v1/tendermint_proxy_connect';
import { ViewService } from '@buf/penumbra-zone_penumbra.connectrpc_es/penumbra/view/v1/view_connect';
import { createRegistry, IMessageTypeRegistry } from '@bufbuild/protobuf';
import { ClientState } from '@buf/cosmos_ibc.bufbuild_es/ibc/lightclients/tendermint/v1/tendermint_pb';

/**
* This type registry is for JSON serialization of protobuf messages.
*
* Some specced messages contain 'Any'-type fields, serialized with type
* annotation URLs resolved with this registry. Chrome runtime messages require
* contents to be JSONifiable, and 'Any' is used to pack for transport at that
* boundary.
* annotation URLs resolved with this registry.
*
* This registry currently contains types for all services used in the
* extension, and should be able to resolve any message type encountered.
* This registry currently contains types for all services used in communication
* with a Penumbra extension, and should be able to resolve any message type
* encountered.
*/

export const typeRegistry: IMessageTypeRegistry = createRegistry(
CustodyService,
ViewService,

AppService,
ClientState,

TendermintProxyService,

AppService,
CompactBlockService,
DexService,
DexSimulationService,
Expand All @@ -45,9 +52,13 @@ export const typeRegistry: IMessageTypeRegistry = createRegistry(
SctService,
ShieldedPoolService,
StakeService,
TendermintProxyService,
);

/**
* Appropriate for any ConnectRPC `Transport` object or protobuf `Any`
* pack/unpack that handles protojson expected to contain these registry types.
* @see https://docs.cosmos.network/v0.50/build/architecture/adr-027-deterministic-protobuf-serialization
*/
export const jsonOptions = {
typeRegistry,

Expand All @@ -57,8 +68,3 @@ export const jsonOptions = {
// write options
emitDefaultValues: false,
};

export const transportOptions = {
defaultTimeoutMs: 10000,
jsonOptions,
};
8 changes: 8 additions & 0 deletions packages/protobuf/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "tsconfig/base.json",
"include": ["src/*.ts"],
"exclude": ["node_modules", "dist"],
"compilerOptions": {
"outDir": "dist"
}
}
5 changes: 1 addition & 4 deletions packages/transport-dom/src/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ export interface ChannelTransportOptions

export const createChannelTransport = ({
getPort,
defaultTimeoutMs,
jsonOptions,
defaultTimeoutMs = 10_000,
}: ChannelTransportOptions) => {
const pending = new Map<string, (response: TransportEvent) => void>();

Expand All @@ -65,9 +65,6 @@ export const createChannelTransport = ({
* that moment, using the `getPort` function from options. Message listeners
* are attached during this process. Failure will reject the first request.
*
* Any createChannelTransport caller should supply `defaultTimeoutMs` or init
* may stall forever.
*
* @returns A promise that resolves when the channel is acquired.
*/
const connect = async () => {
Expand Down
4 changes: 0 additions & 4 deletions packages/types/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,12 @@
},
"devDependencies": {
"@buf/cosmos_ibc.bufbuild_es": "1.9.0-20240327103030-e2006674271c.1",
"@buf/cosmos_ibc.connectrpc_es": "1.4.0-20240327103030-e2006674271c.2",
"@buf/penumbra-zone_penumbra.bufbuild_es": "1.9.0-20240429125510-24b08e70bbc2.1",
"@buf/penumbra-zone_penumbra.connectrpc_es": "1.4.0-20240429125510-24b08e70bbc2.2",
"@bufbuild/protobuf": "^1.9.0"
},
"peerDependencies": {
"@buf/cosmos_ibc.bufbuild_es": "1.9.0-20240327103030-e2006674271c.1",
"@buf/cosmos_ibc.connectrpc_es": "1.4.0-20240327103030-e2006674271c.2",
"@buf/penumbra-zone_penumbra.bufbuild_es": "1.9.0-20240429125510-24b08e70bbc2.1",
"@buf/penumbra-zone_penumbra.connectrpc_es": "1.4.0-20240429125510-24b08e70bbc2.2",
"@bufbuild/protobuf": "^1.9.0"
}
}
1 change: 0 additions & 1 deletion packages/types/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export default defineConfig({
jsonified: './src/jsonified.ts',
'lo-hi': './src/lo-hi.ts',
querier: './src/querier.ts',
registry: './src/registry.ts',
servers: './src/servers.ts',
services: './src/services.ts',
staking: './src/staking.ts',
Expand Down
Loading

0 comments on commit 6fb898a

Please sign in to comment.