Skip to content

Commit

Permalink
Merge pull request #20 from xmtp/rygine/upgrade-js-sdk
Browse files Browse the repository at this point in the history
Upgrade JS SDK
  • Loading branch information
rygine authored Feb 9, 2024
2 parents f2b7e1d + 5f6f1a6 commit 580ced0
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 59 deletions.
5 changes: 5 additions & 0 deletions .changeset/beige-tigers-wash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@xmtp/snap": patch
---

Upgrade to latest XMTP JS SDK, refactor types
2 changes: 1 addition & 1 deletion packages/site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"dependencies": {
"@metamask/providers": "^9.0.0",
"@xmtp/proto": "3.34.0",
"@xmtp/xmtp-js": "11.3.0-beta.13",
"@xmtp/xmtp-js": "11.3.9",
"buffer": "^6.0.3",
"ethers": "^6.6.2",
"react": "^18.2.0",
Expand Down
3 changes: 3 additions & 0 deletions packages/snap/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ module.exports = {
},
],
},
moduleNameMapper: {
'@xmtp/xmtp-js/browser/bundler': '@xmtp/xmtp-js',
},
};
3 changes: 2 additions & 1 deletion packages/snap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"clean": "rm -rf .turbo && rm -rf node_modules && yarn clean:lib",
"clean:lib": "rm -rf dist",
"dev": "yarn clean:lib && mm-snap watch --transpilationMode=localAndDeps",
"eval": "mm-snap eval",
"format": "yarn format:base -w .",
"format:base": "prettier --ignore-path ../../.gitignore",
"format:check": "yarn format:base -c .",
Expand All @@ -36,7 +37,7 @@
},
"dependencies": {
"@xmtp/proto": "3.34.0",
"@xmtp/xmtp-js": "11.3.0-beta.13",
"@xmtp/xmtp-js": "11.3.9",
"async-mutex": "^0.4.0",
"buffer": "^6.0.3",
"protobufjs": "^7.2.4"
Expand Down
4 changes: 2 additions & 2 deletions packages/snap/snap.manifest.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"version": "0.2.1",
"version": "1.3.0",
"description": "A Snap that securely stores your XMTP keys across apps",
"proposedName": "Sign in with XMTP",
"repository": {
"type": "git",
"url": "https://github.com/xmtp/snap.git"
},
"source": {
"shasum": "ax7SLJYHvMBFzUG2SWGVve7Jur9xujigTCIk7tnzsIM=",
"shasum": "XJe/FF4kK9jpK01IKoDgrbBz/nHx4LMTaSewSfLiUjk=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/snap/src/authorizer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable jsdoc/require-jsdoc */
import type { XmtpEnv } from '@xmtp/xmtp-js';
import type { XmtpEnv } from '@xmtp/xmtp-js/browser/bundler';

import { AUTHORIZATION_EXPIRY_MS } from './config';
import storage from './storage';
Expand Down
78 changes: 42 additions & 36 deletions packages/snap/src/handlers.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
/* eslint-disable jsdoc/require-jsdoc */
import { fetcher, keystore as keystoreProto } from '@xmtp/proto';
import type {
InitKeystoreRequest as InitKeystoreRequestType,
InitKeystoreResponse as InitKeystoreResponseType,
GetKeystoreStatusRequest as GetKeystoreStatusRequestType,
GetKeystoreStatusResponse as GetKeystoreStatusResponseType,
// eslint-disable-next-line import/extensions
} from '@xmtp/proto/ts/dist/types/keystore_api/v1/keystore.pb';
import type { InMemoryKeystore, Keystore } from '@xmtp/xmtp-js';
import { PrivateKeyBundleV1, keystoreApiDefs } from '@xmtp/xmtp-js';
import type { Reader, Writer } from 'protobufjs/minimal';
InMemoryKeystore,
KeystoreApiEntries,
KeystoreRPCCodec,
SnapKeystoreApiDefs,
SnapKeystoreApiMethods,
SnapKeystoreInterface,
SnapKeystoreInterfaceRequestValues,
} from '@xmtp/xmtp-js/browser/bundler';
import {
PrivateKeyBundleV1,
keystoreApiDefs,
} from '@xmtp/xmtp-js/browser/bundler';

import type { SnapMeta } from '.';
import { KeyNotFoundError } from './errors';
Expand All @@ -33,54 +36,54 @@ export type SnapResponse = {
res: string | string[];
};

type Codec<MessageType> = {
decode(input: Reader | Uint8Array, length?: number): MessageType;
encode(message: MessageType, writer?: Writer): Writer;
};

export type SnapRPC<Req, Res> = {
req: Codec<Req> | null;
res: Codec<Res>;
};

export async function processProtoRequest<Req, Res>(
rpc: SnapRPC<Req, Res>,
export async function processProtoRequest<
Method extends SnapKeystoreApiMethods,
>(
method: Method,
rpc: SnapKeystoreApiDefs[Method],
request: SnapRequest,
handler: (req?: Req) => Promise<Res>,
handler: (
req?: SnapKeystoreInterfaceRequestValues[Method],
) => ReturnType<SnapKeystoreInterface[Method]>,
): Promise<SnapResponse> {
console.log('Processing request method', method);

if (rpc.req === null) {
const result = await handler();
return serializeResponse(rpc.res, result);
return serializeResponse(
rpc.res as SnapKeystoreApiDefs[Method]['res'],
result,
);
}

if (typeof request.req !== 'string') {
throw new Error(`Expected string request. Got: ${typeof request.req}`);
}

const decodedRequest = rpc.req.decode(b64Decode(request.req));
const decodedRequest = rpc.req.decode(
b64Decode(request.req),
) as SnapKeystoreInterfaceRequestValues[Method];
const result = await handler(decodedRequest);
return serializeResponse(rpc.res, result);
}

function serializeResponse<MessageType>(
codec: Codec<MessageType>,
codec: KeystoreRPCCodec<MessageType>,
res: MessageType,
) {
const responseBytes = codec.encode(res).finish();
return { res: b64Encode(responseBytes, 0, responseBytes.length) };
}

const initKeystoreRPC: SnapRPC<
InitKeystoreRequestType,
InitKeystoreResponseType
> = {
const initKeystoreRPC = {
req: InitKeystoreRequest,
res: InitKeystoreResponse,
};

// Handler for `initKeystore` RPCs, which set the keys in the persistence layer
export async function initKeystore(req: SnapRequest): Promise<SnapResponse> {
return processProtoRequest(
'initKeystore',
initKeystoreRPC,
req,
async (initKeystoreRequest) => {
Expand All @@ -105,15 +108,14 @@ export async function initKeystore(req: SnapRequest): Promise<SnapResponse> {
);
await setKeys(persistence, bundle);

return {};
return {
error: undefined,
};
},
);
}

const getKeystoreStatusRPC: SnapRPC<
GetKeystoreStatusRequestType,
GetKeystoreStatusResponseType
> = {
const getKeystoreStatusRPC = {
req: GetKeystoreStatusRequest,
res: GetKeystoreStatusResponse,
};
Expand All @@ -124,6 +126,7 @@ export async function getKeystoreStatus(
req: SnapRequest,
): Promise<SnapResponse> {
return processProtoRequest(
'getKeystoreStatus',
getKeystoreStatusRPC,
req,
async (getKeystoreStatusRequest) => {
Expand Down Expand Up @@ -157,18 +160,21 @@ export async function getKeystoreStatus(

export function keystoreHandler(backingKeystore: InMemoryKeystore) {
const out: any = {};
for (const [method, apiDef] of Object.entries(keystoreApiDefs)) {
for (const [method, apiDef] of Object.entries(
keystoreApiDefs,
) as KeystoreApiEntries) {
if (!(method in backingKeystore)) {
throw new Error('no method found in keystore');
}

// eslint-disable-next-line no-loop-func
out[method] = async (req: SnapRequest): Promise<SnapResponse> => {
const backingMethod = backingKeystore[method as keyof Keystore];
const backingMethod = backingKeystore[method];
if (typeof backingMethod !== 'function') {
throw new Error('not a function');
}
return processProtoRequest(
method,
apiDef,
req,
backingMethod.bind(backingKeystore) as any,
Expand Down
2 changes: 1 addition & 1 deletion packages/snap/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
text,
type OnRpcRequestHandler,
} from '@metamask/snaps-sdk';
import { type XmtpEnv } from '@xmtp/xmtp-js';
import { type XmtpEnv } from '@xmtp/xmtp-js/browser/bundler';

import authorizer from './authorizer';
import { GET_KEYSTORE_STATUS_METHOD, INIT_KEYSTORE_METHOD } from './config';
Expand Down
2 changes: 1 addition & 1 deletion packages/snap/src/snapPersistence.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Persistence } from '@xmtp/xmtp-js';
import type { Persistence } from '@xmtp/xmtp-js/browser/bundler';

import storage from './storage';

Expand Down
4 changes: 2 additions & 2 deletions packages/snap/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {
InMemoryKeystore,
PrefixedPersistence,
PrivateKeyBundleV1,
} from '@xmtp/xmtp-js';
import type { XmtpEnv, Persistence } from '@xmtp/xmtp-js';
} from '@xmtp/xmtp-js/browser/bundler';
import type { XmtpEnv, Persistence } from '@xmtp/xmtp-js/browser/bundler';

import { KeyNotFoundError } from './errors';
import { type SnapRequest, keystoreHandler } from './handlers';
Expand Down
6 changes: 3 additions & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
"declaration": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"module": "CommonJS",
"moduleResolution": "node",
"module": "ES2015",
"moduleResolution": "Bundler",
"useUnknownInCatchVariables": false,
"sourceMap": true,
"strict": true,
"target": "ES2017"
},
"exclude": ["**/__snapshots__/**", "**/test/**", "**/*.test.ts"]
"exclude": ["**/__snapshots__/**"]
}
30 changes: 19 additions & 11 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8413,7 +8413,7 @@ __metadata:
"@typescript-eslint/parser": "npm:^5.33.0"
"@vitejs/plugin-react": "npm:^4.2.0"
"@xmtp/proto": "npm:3.34.0"
"@xmtp/xmtp-js": "npm:11.3.0-beta.13"
"@xmtp/xmtp-js": "npm:11.3.9"
babel-plugin-styled-components: "npm:^2.1.4"
buffer: "npm:^6.0.3"
cross-env: "npm:^7.0.3"
Expand Down Expand Up @@ -8461,7 +8461,7 @@ __metadata:
"@typescript-eslint/eslint-plugin": "npm:^5.33.0"
"@typescript-eslint/parser": "npm:^5.33.0"
"@xmtp/proto": "npm:3.34.0"
"@xmtp/xmtp-js": "npm:11.3.0-beta.13"
"@xmtp/xmtp-js": "npm:11.3.9"
async-mutex: "npm:^0.4.0"
buffer: "npm:^6.0.3"
eslint: "npm:^8.55.0"
Expand All @@ -8483,25 +8483,26 @@ __metadata:
languageName: unknown
linkType: soft

"@xmtp/user-preferences-bindings-wasm@npm:^0.2.1":
version: 0.2.1
resolution: "@xmtp/user-preferences-bindings-wasm@npm:0.2.1"
checksum: 10/4fc0c49781ae2ddba1f00099f1b9e1f866b93d274a49d91cdbfe6c2dafbe088a279890f7b2a1f3a4d5e0aa6d71993bea83f843b0591609a1df4bba3d7aa66f3a
"@xmtp/user-preferences-bindings-wasm@npm:^0.3.5":
version: 0.3.5
resolution: "@xmtp/user-preferences-bindings-wasm@npm:0.3.5"
checksum: 10/a5a88e81d15c36f4ceb3c837652c09a6ec210f98b3ec6c9cdd9ab58a675540cf34073e9075813538432126178bb906ae4af8d88f15f9a124f508dd332696e843
languageName: node
linkType: hard

"@xmtp/xmtp-js@npm:11.3.0-beta.13":
version: 11.3.0-beta.13
resolution: "@xmtp/xmtp-js@npm:11.3.0-beta.13"
"@xmtp/xmtp-js@npm:11.3.9":
version: 11.3.9
resolution: "@xmtp/xmtp-js@npm:11.3.9"
dependencies:
"@noble/secp256k1": "npm:^1.5.2"
"@xmtp/proto": "npm:^3.34.0"
"@xmtp/user-preferences-bindings-wasm": "npm:^0.2.1"
"@xmtp/user-preferences-bindings-wasm": "npm:^0.3.5"
async-mutex: "npm:^0.4.0"
elliptic: "npm:^6.5.4"
ethers: "npm:^5.5.3"
js-sha3: "npm:^0.9.3"
long: "npm:^5.2.0"
checksum: 10/59610f086b9c1beb983519d757fc568d9a22bcb3e6d16c1cf88a70c3bca9118cca7048f03e16e5e30a4e6271864e690745e73a128c31e12a65bceedc4b0e610e
checksum: 10/b593236c664936d875c2e6cc64d190a77611d70a541b048b64acb5e4b2b08792719e5f649ab73f0f8ae564091e1f7761aeaeb573bbe400f57c96a3d431821de3
languageName: node
linkType: hard

Expand Down Expand Up @@ -17411,6 +17412,13 @@ __metadata:
languageName: node
linkType: hard

"js-sha3@npm:^0.9.3":
version: 0.9.3
resolution: "js-sha3@npm:0.9.3"
checksum: 10/8daacb93b18609a0dc081f2f6199b80a96df36f9975b4b9c7476ae92822e07100b9e1969fc76f4b58e703cd6175f0de7656a99cbb2335cfb554c66f988fbead5
languageName: node
linkType: hard

"js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0":
version: 4.0.0
resolution: "js-tokens@npm:4.0.0"
Expand Down

0 comments on commit 580ced0

Please sign in to comment.