diff --git a/.github/workflows/packages.yml b/.github/workflows/packages.yml new file mode 100644 index 000000000..a69cc137f --- /dev/null +++ b/.github/workflows/packages.yml @@ -0,0 +1,76 @@ +name: Packages + +on: + push: + branches: + - main + + pull_request: + paths: + - "packages/**" + - ".github/workflows/packages.yml" + - "dev/**" + - ".node-version" + - ".nvmrc" + - ".yarnrc.yml" + - "turbo.json" + - "yarn.lock" + +jobs: + typecheck: + name: Typecheck + runs-on: warp-ubuntu-latest-x64-8x + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache: "yarn" + env: + SKIP_YARN_COREPACK_CHECK: "1" + - name: Enable corepack + run: corepack enable + - name: Install dependencies + run: yarn + - name: Typecheck + run: yarn turbo run typecheck --filter='./packages/*' + + test: + name: Test + runs-on: warp-ubuntu-latest-x64-8x + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache: "yarn" + env: + SKIP_YARN_COREPACK_CHECK: "1" + - name: Enable corepack + run: corepack enable + - name: Install dependencies + run: yarn + - name: Start dev environment + run: ./dev/up + - name: Sleep for 5 seconds + run: sleep 5s + - name: Run tests + run: yarn turbo run test --filter='./packages/*' + + build: + name: Build + runs-on: warp-ubuntu-latest-x64-8x + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache: "yarn" + env: + SKIP_YARN_COREPACK_CHECK: "1" + - name: Enable corepack + run: corepack enable + - name: Install dependencies + run: yarn + - name: Build + run: yarn turbo run build --filter='./packages/*' diff --git a/README.md b/README.md index 4fe30cddb..1a17ee267 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,11 @@ To learn more about the contents of this repository, see this README and the REA - [`content-type-text`](content-types/content-type-text): Content type for plain text messages - [`content-type-transaction-reference`](content-types/content-type-transaction-reference): Content type for on-chain transaction references +### Packages + +- [`frames-client`](https://github.com/xmtp/xmtp-js/blob/main/packages/frames-client): XMTP Open Frames client +- [`consent-proof-signature`](https://github.com/xmtp/xmtp-js/blob/main/packages/consent-proof-signature): Lightweight package for creating consent proofs + ## Contributing See our [contribution guide](./CONTRIBUTING.md) to learn more about contributing to this project. diff --git a/content-types/content-type-primitives/package.json b/content-types/content-type-primitives/package.json index 598251203..4c3f47aa6 100644 --- a/content-types/content-type-primitives/package.json +++ b/content-types/content-type-primitives/package.json @@ -67,7 +67,7 @@ }, "devDependencies": { "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^12.1.0", + "@rollup/plugin-typescript": "^12.1.1", "@types/node": "^20.16.11", "happy-dom": "^15.7.4", "rimraf": "^6.0.1", diff --git a/content-types/content-type-reaction/package.json b/content-types/content-type-reaction/package.json index 9a69e9316..3eedda353 100644 --- a/content-types/content-type-reaction/package.json +++ b/content-types/content-type-reaction/package.json @@ -67,7 +67,7 @@ }, "devDependencies": { "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^12.1.0", + "@rollup/plugin-typescript": "^12.1.1", "@types/node": "^20.16.11", "@xmtp/xmtp-js": "^11.6.3", "buffer": "^6.0.3", diff --git a/content-types/content-type-read-receipt/package.json b/content-types/content-type-read-receipt/package.json index caa52a0af..78df7fdd9 100644 --- a/content-types/content-type-read-receipt/package.json +++ b/content-types/content-type-read-receipt/package.json @@ -67,7 +67,7 @@ }, "devDependencies": { "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^12.1.0", + "@rollup/plugin-typescript": "^12.1.1", "@types/node": "^20.16.11", "@xmtp/xmtp-js": "^11.6.3", "buffer": "^6.0.3", diff --git a/content-types/content-type-remote-attachment/package.json b/content-types/content-type-remote-attachment/package.json index 69e2cd5d1..c0aae3d28 100644 --- a/content-types/content-type-remote-attachment/package.json +++ b/content-types/content-type-remote-attachment/package.json @@ -71,7 +71,7 @@ "devDependencies": { "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^12.1.0", + "@rollup/plugin-typescript": "^12.1.1", "@types/node": "^20.16.11", "@xmtp/rollup-plugin-resolve-extensions": "^1.0.1", "@xmtp/xmtp-js": "^11.6.3", diff --git a/content-types/content-type-reply/package.json b/content-types/content-type-reply/package.json index bc3a085b5..132bc7712 100644 --- a/content-types/content-type-reply/package.json +++ b/content-types/content-type-reply/package.json @@ -68,7 +68,7 @@ }, "devDependencies": { "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^12.1.0", + "@rollup/plugin-typescript": "^12.1.1", "@types/node": "^20.16.11", "@xmtp/content-type-remote-attachment": "workspace:*", "@xmtp/xmtp-js": "^11.6.3", diff --git a/content-types/content-type-text/package.json b/content-types/content-type-text/package.json index 80f0053de..088540983 100644 --- a/content-types/content-type-text/package.json +++ b/content-types/content-type-text/package.json @@ -67,7 +67,7 @@ }, "devDependencies": { "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^12.1.0", + "@rollup/plugin-typescript": "^12.1.1", "@types/node": "^20.16.11", "@xmtp/xmtp-js": "^11.6.3", "buffer": "^6.0.3", diff --git a/content-types/content-type-transaction-reference/package.json b/content-types/content-type-transaction-reference/package.json index 16a50176a..eb04bb628 100644 --- a/content-types/content-type-transaction-reference/package.json +++ b/content-types/content-type-transaction-reference/package.json @@ -67,7 +67,7 @@ }, "devDependencies": { "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^12.1.0", + "@rollup/plugin-typescript": "^12.1.1", "@types/node": "^20.16.11", "@xmtp/xmtp-js": "^11.6.3", "buffer": "^6.0.3", diff --git a/package.json b/package.json index 8f98bb7dc..700d6a4df 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "rimraf": "^6.0.1", "turbo": "^2.1.3", "typescript": "^5.6.3", - "typescript-eslint": "^8.9.0" + "typescript-eslint": "^8.10.0" }, "packageManager": "yarn@4.5.0", "engines": { diff --git a/packages/consent-proof-signature/CHANGELOG.md b/packages/consent-proof-signature/CHANGELOG.md new file mode 100644 index 000000000..00abb5989 --- /dev/null +++ b/packages/consent-proof-signature/CHANGELOG.md @@ -0,0 +1,13 @@ +# @xmtp/consent-proof-signature + +## 0.1.3 + +### Patch Changes + +- 8adc23f: Add CommonJS export to `consent-proof-signature` package + +## 0.1.1 + +### Patch Changes + +- 6fbe931: Created package diff --git a/packages/consent-proof-signature/README.md b/packages/consent-proof-signature/README.md new file mode 100644 index 000000000..1ce16cf5d --- /dev/null +++ b/packages/consent-proof-signature/README.md @@ -0,0 +1,24 @@ +# Consent Proof Signature + +## Usage + +```ts +// Sign the message for example with Viem +import { createWalletClient, custom } from "viem"; + +const timestamp = Date.now(); +const message = createConsentMessage(broadcastAddress, timestamp); + +const walletClient = createWalletClient({ + chain: mainnet, + transport: custom((window as any).ethereum!), +}); +const [account] = await walletClient.getAddresses(); +const signature = await walletClient.signMessage({ + account, + message, +}); +const consentProofBytes = createConsentProofPayload(signature, timestamp); +``` + +Now the `consentProofBytes` can be encoded and sent to a service to decode and add in a new conversation invitation diff --git a/packages/consent-proof-signature/package.json b/packages/consent-proof-signature/package.json new file mode 100644 index 000000000..e8d6067a3 --- /dev/null +++ b/packages/consent-proof-signature/package.json @@ -0,0 +1,88 @@ +{ + "name": "@xmtp/consent-proof-signature", + "version": "0.1.3", + "keywords": [ + "xmtp", + "messaging", + "web3", + "sdk", + "js", + "ts", + "javascript", + "typescript" + ], + "homepage": "https://github.com/xmtp/xmtp-js", + "bugs": { + "url": "https://github.com/xmtp/xmtp-js/issues" + }, + "repository": { + "type": "git", + "url": "git@github.com:xmtp/xmtp-js.git", + "directory": "packages/consent-proof-signature" + }, + "license": "MIT", + "author": "XMTP Labs ", + "sideEffects": false, + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "require": "./dist/index.cjs", + "import": "./dist/index.js" + } + }, + "main": "dist/index.cjs", + "module": "dist/index.js", + "browser": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist", + "src", + "!src/**/*.test.*", + "tsconfig.json" + ], + "scripts": { + "build": "yarn clean:dist && yarn rollup -c", + "clean": "rm -rf .turbo && rm -rf node_modules && yarn clean:dist", + "clean:dist": "rm -rf dist", + "dev": "yarn clean:dist && yarn rollup -c --watch", + "test": "vitest run --passWithNoTests", + "typecheck": "tsc", + "typedoc": "typedoc" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome versions", + "last 3 firefox versions", + "last 3 safari versions" + ] + }, + "dependencies": { + "@xmtp/proto": "3.62.1", + "long": "^5.2.3" + }, + "devDependencies": { + "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-typescript": "^12.1.1", + "ethers": "^6.13.1", + "rollup": "^4.24.0", + "rollup-plugin-dts": "^6.1.1", + "rollup-plugin-filesize": "^10.0.0", + "tsconfig": "workspace:*", + "typedoc": "^0.26.4", + "typescript": "^5.6.3", + "vite": "^5.4.9", + "vitest": "^2.1.3" + }, + "packageManager": "yarn@4.5.0", + "publishConfig": { + "access": "public", + "provenance": true, + "registry": "https://registry.npmjs.org/" + } +} diff --git a/packages/consent-proof-signature/rollup.config.js b/packages/consent-proof-signature/rollup.config.js new file mode 100644 index 000000000..455d229ed --- /dev/null +++ b/packages/consent-proof-signature/rollup.config.js @@ -0,0 +1,58 @@ +import terser from "@rollup/plugin-terser"; +import typescript from "@rollup/plugin-typescript"; +import { defineConfig } from "rollup"; +import { dts } from "rollup-plugin-dts"; +import filesize from "rollup-plugin-filesize"; + +const plugins = [ + typescript({ + declaration: false, + declarationMap: false, + }), + filesize({ + showMinifiedSize: false, + }), +]; + +const external = ["@xmtp/proto", "node:crypto", "long"]; + +export default defineConfig([ + { + input: "src/index.ts", + output: { + file: "dist/index.js", + format: "es", + sourcemap: true, + }, + external, + plugins, + }, + { + input: "src/index.ts", + output: { + file: "dist/index.cjs", + format: "cjs", + sourcemap: true, + }, + external, + plugins, + }, + { + input: "src/index.ts", + output: { + file: "dist/browser/index.js", + format: "es", + sourcemap: true, + }, + external, + plugins: [terser(), ...plugins], + }, + { + input: "src/index.ts", + output: { + file: "dist/index.d.ts", + format: "es", + }, + plugins: [dts()], + }, +]); diff --git a/packages/consent-proof-signature/src/index.test.ts b/packages/consent-proof-signature/src/index.test.ts new file mode 100644 index 000000000..223831030 --- /dev/null +++ b/packages/consent-proof-signature/src/index.test.ts @@ -0,0 +1,30 @@ +import { describe, expect, it } from "vitest"; +import { createConsentMessage, createConsentProofPayload } from "."; + +describe("createConsentMessage", () => { + it("should return a signature", () => { + const timestampMs = 1581663600000; + const exampleAddress = "0x1234567890abcdef"; + const signatureMessage = createConsentMessage(exampleAddress, timestampMs); + expect(signatureMessage).toEqual( + "XMTP : Grant inbox consent to sender\n\nCurrent Time: Fri, 14 Feb 2020 07:00:00 GMT\nFrom Address: 0x1234567890abcdef\n\nFor more info: https://xmtp.org/signatures/", + ); + }); +}); + +describe("createConsentProofPayload", () => { + it("should return data of consent proof", () => { + const timestampMs = 1581663600000; + const exampleSignature = "0x1234567890abcdef"; + const signatureMessage = createConsentProofPayload( + exampleSignature, + timestampMs, + ); + expect(signatureMessage).toEqual( + Buffer.from([ + 10, 18, 48, 120, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 97, 98, 99, + 100, 101, 102, 16, 128, 251, 252, 147, 132, 46, 24, 1, + ]), + ); + }); +}); diff --git a/packages/consent-proof-signature/src/index.ts b/packages/consent-proof-signature/src/index.ts new file mode 100644 index 000000000..c854f46c9 --- /dev/null +++ b/packages/consent-proof-signature/src/index.ts @@ -0,0 +1,36 @@ +import { invitation } from "@xmtp/proto"; +import Long from "long"; + +/** + * + * @param peerAddress - Ethereum address of the broadcaster + * @param timestampMs - Timestamp in milliseconds used in the signature + * @returns + */ +export const createConsentMessage = ( + peerAddress: string, + timestampMs: number, +): string => + "XMTP : Grant inbox consent to sender\n" + + "\n" + + `Current Time: ${new Date(timestampMs).toUTCString()}\n` + + `From Address: ${peerAddress}\n` + + "\n" + + "For more info: https://xmtp.org/signatures/"; + +/** + * + * @param signature hex string of the signature + * @param timestampMs timestamp in milliseconds used in the signature + * @returns Uint8Array of the consent proof payload + */ +export const createConsentProofPayload = ( + signature: string, + timestampMs: number, +): Uint8Array => + invitation.ConsentProofPayload.encode({ + signature, + timestamp: Long.fromNumber(timestampMs), + payloadVersion: + invitation.ConsentProofPayloadVersion.CONSENT_PROOF_PAYLOAD_VERSION_1, + }).finish(); diff --git a/packages/consent-proof-signature/tsconfig.json b/packages/consent-proof-signature/tsconfig.json new file mode 100644 index 000000000..8dd79af93 --- /dev/null +++ b/packages/consent-proof-signature/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "tsconfig/react-sdk.json", + "include": ["src", "rollup.config.js", "vitest.config.ts"], + "exclude": ["dist", "node_modules"] +} diff --git a/packages/consent-proof-signature/vitest.config.ts b/packages/consent-proof-signature/vitest.config.ts new file mode 100644 index 000000000..b6ebdaef6 --- /dev/null +++ b/packages/consent-proof-signature/vitest.config.ts @@ -0,0 +1,14 @@ +import { defineConfig, mergeConfig } from "vite"; +import { defineConfig as defineVitestConfig } from "vitest/config"; + +// https://vitejs.dev/config/ +const viteConfig = defineConfig({}); + +const vitestConfig = defineVitestConfig({ + test: { + globals: true, + environment: "happy-dom", + }, +}); + +export default mergeConfig(viteConfig, vitestConfig); diff --git a/packages/frames-client/CHANGELOG.md b/packages/frames-client/CHANGELOG.md new file mode 100644 index 000000000..54c68f6fd --- /dev/null +++ b/packages/frames-client/CHANGELOG.md @@ -0,0 +1,122 @@ +# @xmtp/frames-client + +## 0.5.4 + +### Patch Changes + +- 3fc5b82: Upgraded dependencies + +## 0.5.3 + +### Patch Changes + +- 815ef8f: fix for transaction id + +## 0.5.2 + +### Patch Changes + +- 7db2728: adds transactionId to type + +## 0.5.1 + +### Patch Changes + +- 3ffc491: bumped packages to pass postUrl through in frameInfo + +## 0.5.0 + +### Minor Changes + +- e1ac826: add postTransaction support + +## 0.4.3 + +### Patch Changes + +- cab6fb3: Add support for the state field + +## 0.4.2 + +### Patch Changes + +- d01544d: Add support for optional inputText + +## 0.4.1 + +### Patch Changes + +- f822a36: Upgrade to 0.2.0 of the Frames Proxy client + +## 0.4.0 + +### Minor Changes + +- 893bf17: Use new Frames Proxy with support for frameInfo field + +## 0.3.2 + +### Patch Changes + +- b8297be: Add more exports + +## 0.3.1 + +### Patch Changes + +- 71cb3a3: Fix bug with identity key translation + +## 0.3.0 + +### Minor Changes + +- 65a7cc1: Add new Frames Proxy service and support for redirects and image URLs + +## 0.2.2 + +### Patch Changes + +- c323d3b: Makes the payloads Open Frames compatible and allows overriding the OG proxy URL + +## 0.2.1 + +### Patch Changes + +- 3bbf05c: updated readme + +## 0.2.0 + +### Minor Changes + +- b955667: Updates to the latest format of the proto message and tries to make safe for RN usage + +## 0.1.4 + +### Patch Changes + +- 8b21c05: Updated crypto imports, build, and exports + +## 0.1.3 + +### Patch Changes + +- 4c735d0: Add dynamic crypto import + +## 0.1.2 + +### Patch Changes + +- aa1cc83: Fix polyfill for webcrypto in Node.js + +## 0.1.1 + +### Patch Changes + +- fd952ee: Adds ability to post frame to a destination and see an updated response + +## 0.1.0 + +### Minor Changes + +- a04afac: Add support for preparing signed payloads for the Frames API +- 502c402: Initialize Frames Client diff --git a/packages/frames-client/README.md b/packages/frames-client/README.md new file mode 100644 index 000000000..06505de6d --- /dev/null +++ b/packages/frames-client/README.md @@ -0,0 +1,49 @@ +# Frames Client + +This package is used by messaging apps to render Open Frames. + +## Usage + +```ts +const xmtpClient = await Client.create(wallet); +const framesClient = new FramesClient(xmtpClient); + +const frameUrl = "https://www.myframe.xyz"; +const framePostUrl = "https://www.myframe.xyz/api/post"; //fc:frame:post_url + +// Read data from a frame +const frameMetadata = await framesClient.proxy.readMetadata(frameUrl); + +// Get a proxied image URL, which you can use directly in an tag +const imageUrl = framesClient.proxy.mediaUrl( + frameMetadata.metaTags["fc:frame:image"], +); + +// Handle a click to button 2 from a conversation with topic "/xmtp/0/123" and participant addresses "abc" and "xyz" +const textInputValue = "Your value"; +const payload = await signFrameAction({ + frameUrl, + inputText: textInputValue || undefined, + buttonIndex: 2, + conversationTopic: "/xmtp/0/123", + participantAccountAddresses: ["abc", "xyz"], + address: "0x...", + state: frameMetadata?.frameInfo?.state, // Pulled from frame metadata +}); + +// If the button action type was `post` +const updatedFrameMetadata = await framesClient.proxy.post( + framePostUrl, + payload, +); +// If the button action type was `post_redirect` +const { redirectedTo } = await framesClient.proxy.postRedirect( + framePostUrl, + payload, +); +// If the button action type was `postTransaction` +const transactionInfo = await framesClient.proxy.postTransaction( + framePostUrl, + payload, +); +``` diff --git a/packages/frames-client/package.json b/packages/frames-client/package.json new file mode 100644 index 000000000..58c21ed96 --- /dev/null +++ b/packages/frames-client/package.json @@ -0,0 +1,95 @@ +{ + "name": "@xmtp/frames-client", + "version": "0.5.4", + "keywords": [ + "xmtp", + "messaging", + "web3", + "sdk", + "js", + "ts", + "javascript", + "typescript" + ], + "homepage": "https://github.com/xmtp/xmtp-js", + "bugs": { + "url": "https://github.com/xmtp/xmtp-js/issues" + }, + "repository": { + "type": "git", + "url": "git@github.com:xmtp/xmtp-js.git", + "directory": "packages/frames-client" + }, + "license": "MIT", + "author": "XMTP Labs ", + "sideEffects": false, + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "module": "dist/index.js", + "browser": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist", + "src", + "!src/**/*.test.*", + "tsconfig.json" + ], + "scripts": { + "build": "yarn clean:dist && yarn rollup -c", + "clean": "rm -rf .turbo && rm -rf node_modules && yarn clean:dist", + "clean:dist": "rm -rf dist", + "dev": "yarn clean:dist && yarn rollup -c --watch", + "test": "vitest run --passWithNoTests", + "typecheck": "tsc", + "typedoc": "typedoc" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome versions", + "last 3 firefox versions", + "last 3 safari versions" + ] + }, + "dependencies": { + "@noble/hashes": "^1.4.0", + "@open-frames/proxy-client": "^0.3.3", + "@xmtp/proto": "3.62.1", + "long": "^5.2.3" + }, + "devDependencies": { + "@open-frames/types": "^0.1.1", + "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-typescript": "^12.1.1", + "@xmtp/xmtp-js": "^12.0.0", + "ethers": "^6.13.1", + "rollup": "^4.24.0", + "rollup-plugin-dts": "^6.1.1", + "rollup-plugin-filesize": "^10.0.0", + "rollup-plugin-tsconfig-paths": "^1.5.2", + "tsconfig": "workspace:*", + "typedoc": "^0.26.4", + "typescript": "^5.6.3", + "vite": "^5.4.9", + "vite-tsconfig-paths": "^5.0.1", + "vitest": "^2.1.3" + }, + "peerDependencies": { + "@xmtp/xmtp-js": ">9.3.1" + }, + "packageManager": "yarn@4.5.0", + "publishConfig": { + "access": "public", + "provenance": true, + "registry": "https://registry.npmjs.org/" + } +} diff --git a/packages/frames-client/rollup.config.js b/packages/frames-client/rollup.config.js new file mode 100644 index 000000000..90ec607ab --- /dev/null +++ b/packages/frames-client/rollup.config.js @@ -0,0 +1,56 @@ +import terser from "@rollup/plugin-terser"; +import typescript from "@rollup/plugin-typescript"; +import { defineConfig } from "rollup"; +import { dts } from "rollup-plugin-dts"; +import filesize from "rollup-plugin-filesize"; +import tsConfigPaths from "rollup-plugin-tsconfig-paths"; + +const plugins = [ + tsConfigPaths(), + typescript({ + declaration: false, + declarationMap: false, + }), + filesize({ + showMinifiedSize: false, + }), +]; + +const external = [ + "@xmtp/proto", + "node:crypto", + "@open-frames/proxy-client", + "@noble/hashes/sha256", + "long", +]; + +export default defineConfig([ + { + input: "src/index.ts", + output: { + file: "dist/index.js", + format: "es", + sourcemap: true, + }, + external, + plugins, + }, + { + input: "src/index.ts", + output: { + file: "dist/browser/index.js", + format: "es", + sourcemap: true, + }, + external, + plugins: [terser(), ...plugins], + }, + { + input: "src/index.ts", + output: { + file: "dist/index.d.ts", + format: "es", + }, + plugins: [tsConfigPaths(), dts()], + }, +]); diff --git a/packages/frames-client/src/client.ts b/packages/frames-client/src/client.ts new file mode 100644 index 000000000..f1ce4929e --- /dev/null +++ b/packages/frames-client/src/client.ts @@ -0,0 +1,116 @@ +import { sha256 } from "@noble/hashes/sha256"; +import { + frames, + publicKey as publicKeyProto, + signature as signatureProto, +} from "@xmtp/proto"; +import type { Client } from "@xmtp/xmtp-js"; +import Long from "long"; +import { PROTOCOL_VERSION } from "./constants"; +import { v1ToV2Bundle } from "./converters"; +import OpenFramesProxy from "./proxy"; +import type { + FrameActionInputs, + FramePostPayload, + ReactNativeClient, +} from "./types"; +import { + base64Encode, + buildOpaqueIdentifier, + isReactNativeClient, +} from "./utils"; + +export class FramesClient { + xmtpClient: Client | ReactNativeClient; + + proxy: OpenFramesProxy; + + constructor(xmtpClient: Client | ReactNativeClient, proxy?: OpenFramesProxy) { + this.xmtpClient = xmtpClient; + this.proxy = proxy || new OpenFramesProxy(); + } + + async signFrameAction(inputs: FrameActionInputs): Promise { + const opaqueConversationIdentifier = buildOpaqueIdentifier(inputs); + const { frameUrl, buttonIndex, inputText, state, address, transactionId } = + inputs; + const now = Date.now(); + const timestamp = Long.fromNumber(now); + const toSign: frames.FrameActionBody = { + frameUrl, + buttonIndex, + opaqueConversationIdentifier, + timestamp, + inputText: inputText || "", + unixTimestamp: now, + state: state || "", + address: address || "", + transactionId: transactionId || "", + }; + + const signedAction = await this.buildSignedFrameAction(toSign); + + return { + clientProtocol: `xmtp@${PROTOCOL_VERSION}`, + untrustedData: { + buttonIndex, + opaqueConversationIdentifier, + walletAddress: this.xmtpClient.address, + inputText, + url: frameUrl, + timestamp: now, + unixTimestamp: now, + state, + // The address associated with initiating a transaction + address, + transactionId, + }, + trustedData: { + messageBytes: base64Encode(signedAction), + }, + }; + } + + private async buildSignedFrameAction( + actionBodyInputs: frames.FrameActionBody, + ) { + const actionBody = frames.FrameActionBody.encode(actionBodyInputs).finish(); + + const digest = sha256(actionBody); + const signature = await this.signDigest(digest); + + const publicKeyBundle = await this.getPublicKeyBundle(); + + return frames.FrameAction.encode({ + actionBody, + signature, + signedPublicKeyBundle: v1ToV2Bundle(publicKeyBundle), + }).finish(); + } + + private async signDigest( + digest: Uint8Array, + ): Promise { + if (isReactNativeClient(this.xmtpClient)) { + const signatureBytes = await this.xmtpClient.sign(digest, { + kind: "identity", + }); + return signatureProto.Signature.decode(signatureBytes); + } + + return this.xmtpClient.keystore.signDigest({ + digest, + identityKey: true, + prekeyIndex: undefined, + }); + } + + private async getPublicKeyBundle(): Promise { + if (isReactNativeClient(this.xmtpClient)) { + const bundleBytes = await this.xmtpClient.exportPublicKeyBundle(); + return publicKeyProto.PublicKeyBundle.decode(bundleBytes); + } + + return this.xmtpClient.keystore.getPublicKeyBundle(); + } +} diff --git a/packages/frames-client/src/constants.ts b/packages/frames-client/src/constants.ts new file mode 100644 index 000000000..24c94df51 --- /dev/null +++ b/packages/frames-client/src/constants.ts @@ -0,0 +1,3 @@ +export const OPEN_FRAMES_PROXY_URL = "https://frames.xmtp.chat/"; + +export const PROTOCOL_VERSION = "2024-02-09"; diff --git a/packages/frames-client/src/converters.test.ts b/packages/frames-client/src/converters.test.ts new file mode 100644 index 000000000..bf77320aa --- /dev/null +++ b/packages/frames-client/src/converters.test.ts @@ -0,0 +1,17 @@ +import { PrivateKeyBundleV1, SignedPublicKeyBundle } from "@xmtp/xmtp-js"; +import { Wallet } from "ethers"; +import { describe, expect, it } from "vitest"; +import { v1ToV2Bundle } from "./converters"; + +describe("converters", () => { + it("can convert a valid public key bundle", async () => { + const v1Bundle = await PrivateKeyBundleV1.generate(Wallet.createRandom()); + const publicKeyBundle = v1Bundle.getPublicKeyBundle(); + + const v2Bundle = v1ToV2Bundle(publicKeyBundle); + const v2BundleInstance = new SignedPublicKeyBundle(v2Bundle); + const downgradedBundle = v2BundleInstance.toLegacyBundle(); + + expect(downgradedBundle.equals(publicKeyBundle)).toBe(true); + }); +}); diff --git a/packages/frames-client/src/converters.ts b/packages/frames-client/src/converters.ts new file mode 100644 index 000000000..709385ca7 --- /dev/null +++ b/packages/frames-client/src/converters.ts @@ -0,0 +1,44 @@ +import { publicKey } from "@xmtp/proto"; + +function publicKeyBytesToSign(pubKey: publicKey.PublicKey): Uint8Array { + return publicKey.PublicKey.encode({ + timestamp: pubKey.timestamp, + secp256k1Uncompressed: pubKey.secp256k1Uncompressed, + }).finish(); +} + +function toSignedPublicKey( + v1Key: publicKey.PublicKey, + signedByWallet: boolean, +): publicKey.SignedPublicKey { + if (!v1Key.signature) { + throw new Error("Missing signature"); + } + + let v1Signature = v1Key.signature; + if (signedByWallet) { + v1Signature = { + walletEcdsaCompact: + v1Signature.walletEcdsaCompact || v1Signature.ecdsaCompact, + ecdsaCompact: undefined, + }; + } + + return { + keyBytes: publicKeyBytesToSign(v1Key), + signature: v1Signature, + }; +} + +export function v1ToV2Bundle( + v1Bundle: publicKey.PublicKeyBundle, +): publicKey.SignedPublicKeyBundle { + if (!v1Bundle.identityKey || !v1Bundle.preKey) { + throw new Error("Invalid bundle"); + } + + return { + identityKey: toSignedPublicKey(v1Bundle.identityKey, true), + preKey: toSignedPublicKey(v1Bundle.preKey, false), + }; +} diff --git a/packages/frames-client/src/errors.ts b/packages/frames-client/src/errors.ts new file mode 100644 index 000000000..2548a5676 --- /dev/null +++ b/packages/frames-client/src/errors.ts @@ -0,0 +1,10 @@ +export class ApiError extends Error { + status: number; + + constructor(message: string, status: number) { + super(message); + this.status = status; + } +} + +export class InvalidArgumentsError extends Error {} diff --git a/packages/frames-client/src/index.test.ts b/packages/frames-client/src/index.test.ts new file mode 100644 index 000000000..73e2a44a8 --- /dev/null +++ b/packages/frames-client/src/index.test.ts @@ -0,0 +1,153 @@ +import { sha256 } from "@noble/hashes/sha256"; +import { fetcher, frames } from "@xmtp/proto"; +import { Client, Signature, SignedPublicKey } from "@xmtp/xmtp-js"; +import { Wallet } from "ethers"; +import { beforeEach, describe, expect, it } from "vitest"; +import { FramesClient } from "./client"; + +const { b64Decode } = fetcher; + +describe("signFrameAction", () => { + let client: Client; + let framesClient: FramesClient; + beforeEach(async () => { + client = await Client.create(Wallet.createRandom()); + framesClient = new FramesClient(client); + }); + it("should sign a frame action with a valid signature", async () => { + const frameUrl = "https://example.com"; + const buttonIndex = 1; + + const signedPayload = await framesClient.signFrameAction({ + frameUrl, + buttonIndex, + conversationTopic: "foo", + participantAccountAddresses: ["amal", "bola"], + state: "state", + address: "0x...", + transactionId: "123", + }); + + // Below addresses are typically the same but can technically be different + // walletAddress references address of XMTP client + expect(signedPayload.untrustedData.walletAddress).toEqual(client.address); + + // address references the address associated with initiating a transaction + expect(signedPayload.untrustedData.address).toEqual("0x..."); + expect(signedPayload.untrustedData.transactionId).toEqual("123"); + + expect(signedPayload.untrustedData.url).toEqual(frameUrl); + expect(signedPayload.untrustedData.buttonIndex).toEqual(buttonIndex); + expect( + signedPayload.untrustedData.opaqueConversationIdentifier, + ).toBeDefined(); + expect(signedPayload.untrustedData.timestamp).toBeGreaterThan(0); + + const signedPayloadProto = frames.FrameAction.decode( + b64Decode(signedPayload.trustedData.messageBytes), + ); + expect(signedPayloadProto.actionBody).toBeDefined(); + expect(signedPayloadProto.signature).toBeDefined(); + expect(signedPayloadProto.signedPublicKeyBundle).toBeDefined(); + + const signedPayloadBody = frames.FrameActionBody.decode( + signedPayloadProto.actionBody, + ); + + expect(signedPayloadBody.buttonIndex).toEqual(buttonIndex); + expect(signedPayloadBody.frameUrl).toEqual(frameUrl); + expect(signedPayloadBody.opaqueConversationIdentifier).toBeDefined(); + expect(signedPayloadBody.state).toEqual("state"); + + if ( + !signedPayloadProto.signature || + !signedPayloadProto.signedPublicKeyBundle?.identityKey + ) { + throw new Error("Missing signature"); + } + + const signatureInstance = new Signature(signedPayloadProto.signature); + const digest = sha256(signedPayloadProto.actionBody); + // Ensure the signature is valid + expect( + signatureInstance + .getPublicKey(digest) + ?.equals( + new SignedPublicKey( + signedPayloadProto.signedPublicKeyBundle.identityKey, + ).toLegacyKey(), + ), + ); + }); + + // Will add E2E tests back once we have Frames deployed with the new schema + it("works e2e", async () => { + const frameUrl = + "https://fc-polls-five.vercel.app/polls/01032f47-e976-42ee-9e3d-3aac1324f4b8"; + const metadata = await framesClient.proxy.readMetadata(frameUrl); + expect(metadata).toBeDefined(); + expect(metadata.frameInfo).toMatchObject({ + acceptedClients: { + farcaster: "vNext", + }, + buttons: { + "1": { + label: "Yes", + }, + "2": { + label: "No", + }, + }, + image: { + content: + "https://fc-polls-five.vercel.app/api/image?id=01032f47-e976-42ee-9e3d-3aac1324f4b8", + }, + postUrl: + "https://fc-polls-five.vercel.app/api/vote?id=01032f47-e976-42ee-9e3d-3aac1324f4b8", + }); + const signedPayload = await framesClient.signFrameAction({ + frameUrl, + buttonIndex: 1, + conversationTopic: "foo", + participantAccountAddresses: ["amal", "bola"], + }); + const postUrl = metadata.extractedTags["fc:frame:post_url"]; + const response = await framesClient.proxy.post(postUrl, signedPayload); + expect(response).toBeDefined(); + expect(response.extractedTags["fc:frame"]).toEqual("vNext"); + + const imageUrl = response.extractedTags["fc:frame:image"]; + const mediaUrl = framesClient.proxy.mediaUrl(imageUrl); + + const downloadedMedia = await fetch(mediaUrl); + expect(downloadedMedia.ok).toBeTruthy(); + expect(downloadedMedia.headers.get("content-type")).toEqual("image/png"); + }); + + it("sends back the button postUrl for a tx frame in frame info", async () => { + const frameUrl = + "https://tx-boilerplate-frame-git-main-xmtp-labs.vercel.app/"; + const metadata = await framesClient.proxy.readMetadata(frameUrl); + expect(metadata).toBeDefined(); + expect(metadata.frameInfo).toMatchObject({ + acceptedClients: { + xmtp: "2024-02-09", + farcaster: "vNext", + }, + buttons: { + "1": { + label: "Make transaction", + action: "tx", + target: + "https://tx-boilerplate-frame-git-main-xmtp-labs.vercel.app/api/transaction", + postUrl: + "https://tx-boilerplate-frame-git-main-xmtp-labs.vercel.app/api/transaction-success", + }, + }, + image: { + content: + "https://tx-boilerplate-frame-git-main-xmtp-labs.vercel.app/api/og?transaction=null", + }, + }); + }); +}); diff --git a/packages/frames-client/src/index.ts b/packages/frames-client/src/index.ts new file mode 100644 index 000000000..56201315d --- /dev/null +++ b/packages/frames-client/src/index.ts @@ -0,0 +1,4 @@ +export type * from "./types"; +export * from "./constants"; +export { FramesClient } from "./client"; +export { default as OpenFramesProxy } from "./proxy"; diff --git a/packages/frames-client/src/proxy.ts b/packages/frames-client/src/proxy.ts new file mode 100644 index 000000000..a2e3af112 --- /dev/null +++ b/packages/frames-client/src/proxy.ts @@ -0,0 +1,45 @@ +import { OpenFramesProxy as BaseProxy } from "@open-frames/proxy-client"; +import { OPEN_FRAMES_PROXY_URL } from "./constants"; +import type { + FramePostPayload, + FramesApiRedirectResponse, + FramesApiResponse, + FramesTransactionApiResponse, +} from "./types"; + +export default class OpenFramesProxy { + inner: BaseProxy; + + constructor(baseUrl: string = OPEN_FRAMES_PROXY_URL) { + this.inner = new BaseProxy(baseUrl); + } + + readMetadata(url: string) { + return this.inner.readMetadata(url); + } + + post(url: string, payload: FramePostPayload): Promise { + return this.inner.post(url, payload); + } + + postRedirect( + url: string, + payload: FramePostPayload, + ): Promise { + return this.inner.postRedirect(url, payload); + } + + postTransaction( + url: string, + payload: FramePostPayload, + ): Promise { + return this.inner.postTransaction(url, payload); + } + + mediaUrl(url: string): string { + if (url.startsWith("data:")) { + return url; + } + return this.inner.mediaUrl(url); + } +} diff --git a/packages/frames-client/src/types.ts b/packages/frames-client/src/types.ts new file mode 100644 index 000000000..e2de54477 --- /dev/null +++ b/packages/frames-client/src/types.ts @@ -0,0 +1,60 @@ +import type { + GetMetadataResponse, + PostRedirectResponse, + TransactionResponse, +} from "@open-frames/proxy-client"; +import type { OpenFramesUntrustedData } from "@open-frames/types"; + +export type FramesApiResponse = GetMetadataResponse; + +export type FramesApiRedirectResponse = PostRedirectResponse; + +export type FramesTransactionApiResponse = TransactionResponse; + +export type FramePostUntrustedData = OpenFramesUntrustedData & { + walletAddress: string; // Untrusted version of the wallet address + opaqueConversationIdentifier: string; // A hash of the conversation topic and the participants + unixTimestamp: number; +}; + +export type FramePostTrustedData = { + messageBytes: string; +}; + +export type FramePostPayload = { + clientProtocol: `xmtp@${string}`; + untrustedData: FramePostUntrustedData; + trustedData: FramePostTrustedData; +}; + +type DmActionInputs = { + conversationTopic: string; + participantAccountAddresses: string[]; +}; + +type GroupActionInputs = { + groupId: Uint8Array; + groupSecret: Uint8Array; +}; + +type ConversationActionInputs = DmActionInputs | GroupActionInputs; + +export type FrameActionInputs = { + frameUrl: string; + buttonIndex: number; + inputText?: string; + state?: string; + address?: string; + transactionId?: string; +} & ConversationActionInputs; + +type KeyType = { + kind: "identity" | "prekey"; + prekeyIndex?: number | undefined; +}; + +export type ReactNativeClient = { + address: string; + exportPublicKeyBundle(): Promise; + sign(digest: Uint8Array, type: KeyType): Promise; +}; diff --git a/packages/frames-client/src/utils.test.ts b/packages/frames-client/src/utils.test.ts new file mode 100644 index 000000000..f3ce14c78 --- /dev/null +++ b/packages/frames-client/src/utils.test.ts @@ -0,0 +1,60 @@ +import { webcrypto } from "crypto"; +import { describe, expect, it } from "vitest"; +import { + base64Encode, + buildOpaqueIdentifier, + concatArrays, + concatStringsToBytes, +} from "./utils"; + +describe("concatArrays", () => { + it("should work with a single array", () => { + const input = new Uint8Array([1, 2, 3]); + const result = concatArrays(input); + expect(result).toEqual(input); + }); + + it("should work with multiple arrays", () => { + const input1 = new Uint8Array([1, 2, 3]); + const input2 = new Uint8Array([4, 5, 6]); + const result = concatArrays(input1, input2); + expect(result).toEqual(new Uint8Array([1, 2, 3, 4, 5, 6])); + }); +}); + +describe("concatStringsToBytes", () => { + it("should work with a single string", () => { + const input = "abc"; + const result = concatStringsToBytes(input); + expect(result).toEqual(new TextEncoder().encode(input)); + }); + + it("should work with multiple strings", () => { + const input1 = "abc"; + const input2 = "def"; + const result = concatStringsToBytes(input1, input2); + expect(result).toEqual(new TextEncoder().encode(input1 + input2)); + }); +}); + +describe("buildOpaqueIdentifier", () => { + it("should return a base64 encoded sha256 hash of the inputs", async () => { + const inputs = { + frameUrl: "https://example.com", + buttonIndex: 2, + conversationTopic: "Foo", + participantAccountAddresses: ["Bola", "Amal"], + }; + const result = buildOpaqueIdentifier(inputs); + expect(result).toEqual( + base64Encode( + new Uint8Array( + await webcrypto.subtle.digest( + "SHA-256", + new TextEncoder().encode("fooamalbola"), + ), + ), + ), + ); + }); +}); diff --git a/packages/frames-client/src/utils.ts b/packages/frames-client/src/utils.ts new file mode 100644 index 000000000..78f830867 --- /dev/null +++ b/packages/frames-client/src/utils.ts @@ -0,0 +1,56 @@ +import { sha256 } from "@noble/hashes/sha256"; +import { fetcher } from "@xmtp/proto"; +import type { Client } from "@xmtp/xmtp-js"; +import { InvalidArgumentsError } from "./errors"; +import type { FrameActionInputs, ReactNativeClient } from "./types"; + +const { b64Encode } = fetcher; + +export function concatArrays(...arrays: Uint8Array[]): Uint8Array { + return new Uint8Array( + arrays.reduce((acc, arr) => acc.concat(Array.from(arr)), []), + ); +} + +export function concatStringsToBytes(...arrays: string[]): Uint8Array { + return new TextEncoder().encode(arrays.join("")); +} + +export function base64Encode(input: Uint8Array): string { + return b64Encode(input, 0, input.length); +} + +export function buildOpaqueIdentifier(inputs: FrameActionInputs): string { + if ("groupId" in inputs && "groupSecret" in inputs) { + return base64Encode( + sha256(concatArrays(inputs.groupId, inputs.groupSecret)), + ); + } + + const { conversationTopic, participantAccountAddresses } = inputs; + if (!conversationTopic || !participantAccountAddresses.length) { + throw new InvalidArgumentsError( + "Missing conversation topic or participants", + ); + } + + return base64Encode( + sha256( + concatStringsToBytes( + conversationTopic.toLowerCase(), + ...participantAccountAddresses.map((p) => p.toLowerCase()).sort(), + ), + ), + ); +} + +export function isReactNativeClient( + client: Client | ReactNativeClient, +): client is ReactNativeClient { + const assertedClient = client as ReactNativeClient; + return ( + typeof assertedClient.sign === "function" && + typeof assertedClient.exportPublicKeyBundle === "function" && + !("keystore" in client) + ); +} diff --git a/packages/frames-client/tsconfig.json b/packages/frames-client/tsconfig.json new file mode 100644 index 000000000..8dd79af93 --- /dev/null +++ b/packages/frames-client/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "tsconfig/react-sdk.json", + "include": ["src", "rollup.config.js", "vitest.config.ts"], + "exclude": ["dist", "node_modules"] +} diff --git a/packages/frames-client/vitest.config.ts b/packages/frames-client/vitest.config.ts new file mode 100644 index 000000000..5b9029d98 --- /dev/null +++ b/packages/frames-client/vitest.config.ts @@ -0,0 +1,18 @@ +import { defineConfig, mergeConfig } from "vite"; +import tsconfigPaths from "vite-tsconfig-paths"; +import { defineConfig as defineVitestConfig } from "vitest/config"; + +// https://vitejs.dev/config/ +const viteConfig = defineConfig({ + plugins: [tsconfigPaths()], +}); + +const vitestConfig = defineVitestConfig({ + test: { + globals: true, + environment: "happy-dom", + testTimeout: 60000, + }, +}); + +export default mergeConfig(viteConfig, vitestConfig); diff --git a/sdks/js-sdk/package.json b/sdks/js-sdk/package.json index 9d1fc8562..8caf45a67 100644 --- a/sdks/js-sdk/package.json +++ b/sdks/js-sdk/package.json @@ -110,7 +110,7 @@ "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^12.1.0", + "@rollup/plugin-typescript": "^12.1.1", "@types/benchmark": "^2.1.5", "@types/bl": "^5.1.0", "@types/callback-to-async-iterator": "^1.1.7", diff --git a/sdks/node-sdk/package.json b/sdks/node-sdk/package.json index 0aae5a4da..95ce99c5f 100644 --- a/sdks/node-sdk/package.json +++ b/sdks/node-sdk/package.json @@ -55,7 +55,7 @@ }, "devDependencies": { "@rollup/plugin-json": "^6.1.0", - "@rollup/plugin-typescript": "^12.1.0", + "@rollup/plugin-typescript": "^12.1.1", "@types/node": "^20.16.11", "@vitest/coverage-v8": "^2.1.3", "@xmtp/xmtp-js": "workspace:^", diff --git a/shared/encryption/package.json b/shared/encryption/package.json index cec0deea4..5b2f2181c 100644 --- a/shared/encryption/package.json +++ b/shared/encryption/package.json @@ -57,7 +57,7 @@ }, "devDependencies": { "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^12.1.0", + "@rollup/plugin-typescript": "^12.1.1", "@types/node": "^20.16.11", "@vitest/coverage-v8": "^2.1.3", "@xmtp/rollup-plugin-resolve-extensions": "1.0.1", diff --git a/shared/tsconfig/react-app.json b/shared/tsconfig/react-app.json new file mode 100644 index 000000000..5481553f5 --- /dev/null +++ b/shared/tsconfig/react-app.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "React App", + "extends": "./base.json", + "compilerOptions": { + "jsx": "react-jsx", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "module": "ESNext", + "moduleResolution": "Bundler", + "target": "ESNext" + } +} diff --git a/shared/tsconfig/react-sdk.json b/shared/tsconfig/react-sdk.json new file mode 100644 index 000000000..0062b43ab --- /dev/null +++ b/shared/tsconfig/react-sdk.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "React SDK", + "extends": "./base.json", + "compilerOptions": { + "jsx": "react-jsx", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "module": "ESNext", + "moduleResolution": "Bundler", + "target": "ESNext", + "types": ["vitest", "vitest/globals"] + } +} diff --git a/turbo.json b/turbo.json index 7980eaa6b..52268248f 100644 --- a/turbo.json +++ b/turbo.json @@ -30,6 +30,17 @@ "@xmtp/content-type-reply#test": { "dependsOn": ["@xmtp/content-type-remote-attachment#build"], "outputs": [] + }, + "@xmtp/content-type-remote-attachment#test": { + "dependsOn": ["@xmtp/consent-proof-signature#build"], + "outputs": [] + }, + "@xmtp/frames-client#test": { + "dependsOn": [ + "@xmtp/consent-proof-signature#build", + "@xmtp/content-type-text#build" + ], + "outputs": [] } } } diff --git a/yarn.lock b/yarn.lock index 511ceeba0..a16d4b0b6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -91,15 +91,15 @@ __metadata: linkType: hard "@babel/compat-data@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/compat-data@npm:7.25.7" - checksum: 10/8fdc451e0ed9e22d1324d504b84d4452ba6f4a806b0f5c364996ee4c2a77293f79ecf4da03033acb625c90bac115c61617eb6c894c2b88486724bcbe3af1a6eb + version: 7.25.8 + resolution: "@babel/compat-data@npm:7.25.8" + checksum: 10/269fcb0d89e02e36c8a11e0c1b960a6b4204e88f59f20c374d28f8e318f4cd5ded42dfedc4b54162065e6a10f71c0de651f5ed3f9b45d3a4b52240196df85726 languageName: node linkType: hard "@babel/core@npm:^7.24.0": - version: 7.25.7 - resolution: "@babel/core@npm:7.25.7" + version: 7.25.8 + resolution: "@babel/core@npm:7.25.8" dependencies: "@ampproject/remapping": "npm:^2.2.0" "@babel/code-frame": "npm:^7.25.7" @@ -107,16 +107,16 @@ __metadata: "@babel/helper-compilation-targets": "npm:^7.25.7" "@babel/helper-module-transforms": "npm:^7.25.7" "@babel/helpers": "npm:^7.25.7" - "@babel/parser": "npm:^7.25.7" + "@babel/parser": "npm:^7.25.8" "@babel/template": "npm:^7.25.7" "@babel/traverse": "npm:^7.25.7" - "@babel/types": "npm:^7.25.7" + "@babel/types": "npm:^7.25.8" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 10/f5fb7fb1e3ce357485cb33fe7984051a2d416472370b33144ae809df86a4663192b58cf0d828d40674d30f485790f3dd5aaf72eb659487673a4dc4be47cb3575 + checksum: 10/31eb1a8ca1a3cc0026060720eb290e68205d95c5c00fbd831e69ddc0810f5920b8eb2749db1889ac0a0312b6eddbf321d18a996a88858f3b75c9582bef9ec1e4 languageName: node linkType: hard @@ -222,14 +222,14 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.24.0, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/parser@npm:7.25.7" +"@babel/parser@npm:^7.24.0, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.25.7, @babel/parser@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/parser@npm:7.25.8" dependencies: - "@babel/types": "npm:^7.25.7" + "@babel/types": "npm:^7.25.8" bin: parser: ./bin/babel-parser.js - checksum: 10/98eaa81bd378734a5f2790f02c7c076ecaba0839217445b4b84f45a7b391d640c34034253231a5bb2b2daf8204796f03584c3f94c10d46b004369bbb426a418f + checksum: 10/0396eb71e379903cedb43862f84ebb1bec809c41e82b4894d2e6e83b8e8bc636ba6eff45382e615baefdb2399ede76ca82247ecc3a9877ac16eb3140074a3276 languageName: node linkType: hard @@ -268,14 +268,14 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.24.0, @babel/types@npm:^7.25.4, @babel/types@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/types@npm:7.25.7" +"@babel/types@npm:^7.24.0, @babel/types@npm:^7.25.4, @babel/types@npm:^7.25.7, @babel/types@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/types@npm:7.25.8" dependencies: "@babel/helper-string-parser": "npm:^7.25.7" "@babel/helper-validator-identifier": "npm:^7.25.7" to-fast-properties: "npm:^2.0.0" - checksum: 10/4504e16a95b6a67d50cfaa389bcbc0621019084cff73784ad4797f82d1bb76c870cb0abb6d9881d5776eb06b4607419a2b1205a08c3e87b152d74bd0884b822a + checksum: 10/973108dbb189916bb87360f2beff43ae97f1b08f1c071bc6499d363cce48b3c71674bf3b59dfd617f8c5062d1c76dc2a64232bc07b6ccef831fd0c06162d44d9 languageName: node linkType: hard @@ -1377,7 +1377,18 @@ __metadata: languageName: node linkType: hard -"@metamask/json-rpc-engine@npm:^9.0.1, @metamask/json-rpc-engine@npm:^9.0.3": +"@metamask/json-rpc-engine@npm:^10.0.0": + version: 10.0.0 + resolution: "@metamask/json-rpc-engine@npm:10.0.0" + dependencies: + "@metamask/rpc-errors": "npm:^7.0.0" + "@metamask/safe-event-emitter": "npm:^3.0.0" + "@metamask/utils": "npm:^9.1.0" + checksum: 10/2c401a4a64392aeb11c4f7ca8d7b458ba1106cff1e0b3dba8b3e0cc90e82f8c55ac2dc9fdfcd914b289e3298fb726d637cf21382336dde2c207cf76129ce5eab + languageName: node + linkType: hard + +"@metamask/json-rpc-engine@npm:^9.0.1": version: 9.0.3 resolution: "@metamask/json-rpc-engine@npm:9.0.3" dependencies: @@ -1389,24 +1400,24 @@ __metadata: linkType: hard "@metamask/json-rpc-middleware-stream@npm:^8.0.1": - version: 8.0.3 - resolution: "@metamask/json-rpc-middleware-stream@npm:8.0.3" + version: 8.0.4 + resolution: "@metamask/json-rpc-middleware-stream@npm:8.0.4" dependencies: - "@metamask/json-rpc-engine": "npm:^9.0.3" + "@metamask/json-rpc-engine": "npm:^10.0.0" "@metamask/safe-event-emitter": "npm:^3.0.0" "@metamask/utils": "npm:^9.1.0" readable-stream: "npm:^3.6.2" - checksum: 10/21299e30f735b56d50737739cdc711667e7862b27bf4ce6b73bfa5b9cd7763d5a3022caf1bb2786600169674ac87e7a141321752b92ddd46c12f41dd10b666ae + checksum: 10/93c842e1ac8e624c65d888cb3539b38ade5b8415ea45f649d78dad91e7139f11fa96bbf89136998d21def7711b3f710939f8e4498ce31a6cf461892e3f4ba176 languageName: node linkType: hard "@metamask/object-multiplex@npm:^2.0.0": - version: 2.0.0 - resolution: "@metamask/object-multiplex@npm:2.0.0" + version: 2.1.0 + resolution: "@metamask/object-multiplex@npm:2.1.0" dependencies: once: "npm:^1.4.0" readable-stream: "npm:^3.6.2" - checksum: 10/54baea752a3ac7c2742c376512e00d4902d383e9da8787574d3b21eb0081523309e24e3915a98f3ae0341d65712b6832d2eb7eeb862f4ef0da1ead52dcde5387 + checksum: 10/e119f695e89eb20c3174f8ac6d74587498d85cff92c37e83e167cb758b3d3147d5b5e1a997d6198d430ebcf2cede6265bf5d4513fe96dbb2d82bbc6167752caa languageName: node linkType: hard @@ -1441,6 +1452,16 @@ __metadata: languageName: node linkType: hard +"@metamask/rpc-errors@npm:^7.0.0": + version: 7.0.0 + resolution: "@metamask/rpc-errors@npm:7.0.0" + dependencies: + "@metamask/utils": "npm:^9.0.0" + fast-safe-stringify: "npm:^2.0.6" + checksum: 10/f25e2a5506d4d0d6193c88aef8f035ec189a1177f8aee8fa01c9a33d73b1536ca7b5eea2fb33a477768bbd2abaf16529e68f0b3cf714387e5d6c9178225354fd + languageName: node + linkType: hard + "@metamask/safe-event-emitter@npm:^3.0.0, @metamask/safe-event-emitter@npm:^3.1.1": version: 3.1.1 resolution: "@metamask/safe-event-emitter@npm:3.1.1" @@ -1660,6 +1681,31 @@ __metadata: languageName: node linkType: hard +"@open-frames/proxy-client@npm:^0.3.3": + version: 0.3.3 + resolution: "@open-frames/proxy-client@npm:0.3.3" + dependencies: + "@open-frames/proxy-types": "npm:0.2.3" + checksum: 10/c75c2fbd455aae83c85bcb06308d92081b8ddfda2d26771ac9c75c5b7baea06cf2fba65fe314d2ca900a4f5b2300563d8e83e309772cade77049c62c2c23de99 + languageName: node + linkType: hard + +"@open-frames/proxy-types@npm:0.2.3": + version: 0.2.3 + resolution: "@open-frames/proxy-types@npm:0.2.3" + peerDependencies: + typescript: ^5.3.3 + checksum: 10/ab7effbb4a90e26e23b42c36c19cffc83ef50401ecf35570765516c92acc96e6461da846130a52de3e3e30ca77f64d1049a79adc012211d6eabfdf5993bee46d + languageName: node + linkType: hard + +"@open-frames/types@npm:^0.1.1": + version: 0.1.1 + resolution: "@open-frames/types@npm:0.1.1" + checksum: 10/2e23b984123f760e4fd4f205fb50e89725679563f8830a86d9d0c436315b6df02d336a4ab06c583b31c568103bc2a82dbe23d36356909a80fc9a1c0026cc04ee + languageName: node + linkType: hard + "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -1795,9 +1841,9 @@ __metadata: languageName: node linkType: hard -"@rollup/plugin-typescript@npm:^12.1.0": - version: 12.1.0 - resolution: "@rollup/plugin-typescript@npm:12.1.0" +"@rollup/plugin-typescript@npm:^12.1.1": + version: 12.1.1 + resolution: "@rollup/plugin-typescript@npm:12.1.1" dependencies: "@rollup/pluginutils": "npm:^5.1.0" resolve: "npm:^1.22.1" @@ -1810,7 +1856,7 @@ __metadata: optional: true tslib: optional: true - checksum: 10/93e67032377278be3658988423588f2941eb55ccb540312ab847c050ea62a57d056d3f80c292bf463e90cbc71795498805120a0f244040d8304ba57d9bb8c09e + checksum: 10/838d5e67d1b383154fab7ae1b0c58e91844c70380210b12c1d5f2ed5d2264d4fbd21ff991a13a4a72078dce897b5c482c70554a21671269219aa9d2525f14dcd languageName: node linkType: hard @@ -2234,18 +2280,20 @@ __metadata: linkType: hard "@types/node@npm:*, @types/node@npm:>=13.7.0": - version: 22.7.5 - resolution: "@types/node@npm:22.7.5" + version: 22.7.6 + resolution: "@types/node@npm:22.7.6" dependencies: undici-types: "npm:~6.19.2" - checksum: 10/e8ba102f8c1aa7623787d625389be68d64e54fcbb76d41f6c2c64e8cf4c9f4a2370e7ef5e5f1732f3c57529d3d26afdcb2edc0101c5e413a79081449825c57ac + checksum: 10/46a8d6bcd61098ece36f790c4bd500537cf78fe075dbfe48f1e07a29efa6cba18cff3b2564aed80fb183244f5d9a95a63b09e27c9f5181ed927ac16ef493bd95 languageName: node linkType: hard -"@types/node@npm:18.15.13": - version: 18.15.13 - resolution: "@types/node@npm:18.15.13" - checksum: 10/b9bbe923573797ef7c5fd2641a6793489e25d9369c32aeadcaa5c7c175c85b42eb12d6fe173f6781ab6f42eaa1ebd9576a419eeaa2a1ec810094adb8adaa9a54 +"@types/node@npm:22.7.5": + version: 22.7.5 + resolution: "@types/node@npm:22.7.5" + dependencies: + undici-types: "npm:~6.19.2" + checksum: 10/e8ba102f8c1aa7623787d625389be68d64e54fcbb76d41f6c2c64e8cf4c9f4a2370e7ef5e5f1732f3c57529d3d26afdcb2edc0101c5e413a79081449825c57ac languageName: node linkType: hard @@ -2257,11 +2305,11 @@ __metadata: linkType: hard "@types/node@npm:^20.16.11": - version: 20.16.11 - resolution: "@types/node@npm:20.16.11" + version: 20.16.12 + resolution: "@types/node@npm:20.16.12" dependencies: undici-types: "npm:~6.19.2" - checksum: 10/6d2f92b7b320c32ba0c2bc54d21651bd21690998a2e27f00d15019d4db3e0ec30fce85332efed5e37d4cda078ff93ea86ee3e92b76b7a25a9b92a52a039b60b2 + checksum: 10/689badb5af2a1a03553a6d21880fa4aabb8cf028b7db1a03be889c0026047a780ac37c83df5dca036f02f5dc3cc4000254fa40d2cadd5df0e9bd6f43dae6eac6 languageName: node linkType: hard @@ -2289,15 +2337,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:8.9.0": - version: 8.9.0 - resolution: "@typescript-eslint/eslint-plugin@npm:8.9.0" +"@typescript-eslint/eslint-plugin@npm:8.10.0": + version: 8.10.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.10.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:8.9.0" - "@typescript-eslint/type-utils": "npm:8.9.0" - "@typescript-eslint/utils": "npm:8.9.0" - "@typescript-eslint/visitor-keys": "npm:8.9.0" + "@typescript-eslint/scope-manager": "npm:8.10.0" + "@typescript-eslint/type-utils": "npm:8.10.0" + "@typescript-eslint/utils": "npm:8.10.0" + "@typescript-eslint/visitor-keys": "npm:8.10.0" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" @@ -2308,66 +2356,66 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/c1858656d7ab3d37674759c838422d8a1b7540e54a25c67c7508c38ee76594a98e8f1f269749f08700f93a7a425e0dca6eb6d031b36539c537e10a32edb4975c + checksum: 10/7a53a40b16188c95651b3d69facbfdeacba93da42850a3fb35dfc08318a5db063f42fea2b22bf8756c54bc26edeefcab8fabc39ce3d717d5f9bc765f4922b58a languageName: node linkType: hard -"@typescript-eslint/parser@npm:8.9.0": - version: 8.9.0 - resolution: "@typescript-eslint/parser@npm:8.9.0" +"@typescript-eslint/parser@npm:8.10.0": + version: 8.10.0 + resolution: "@typescript-eslint/parser@npm:8.10.0" dependencies: - "@typescript-eslint/scope-manager": "npm:8.9.0" - "@typescript-eslint/types": "npm:8.9.0" - "@typescript-eslint/typescript-estree": "npm:8.9.0" - "@typescript-eslint/visitor-keys": "npm:8.9.0" + "@typescript-eslint/scope-manager": "npm:8.10.0" + "@typescript-eslint/types": "npm:8.10.0" + "@typescript-eslint/typescript-estree": "npm:8.10.0" + "@typescript-eslint/visitor-keys": "npm:8.10.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.57.0 || ^9.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/6f73af7782856b292b37e43dde83c5babbbdae28da1a4fed764474a9ccbbfcce25903cedde82d6847ad53e0c1a7c2ed53f087b281e6f1408a064498169c0e2d1 + checksum: 10/b3059e112f1b85176bb5abdd403adb0b19a7560d3bcd5a6efc414d06d9aeef70d00fb6f0fd8e4923d914d4d15de35a681bdf8f55301457b5b244d7027c38f330 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.9.0": - version: 8.9.0 - resolution: "@typescript-eslint/scope-manager@npm:8.9.0" +"@typescript-eslint/scope-manager@npm:8.10.0": + version: 8.10.0 + resolution: "@typescript-eslint/scope-manager@npm:8.10.0" dependencies: - "@typescript-eslint/types": "npm:8.9.0" - "@typescript-eslint/visitor-keys": "npm:8.9.0" - checksum: 10/44dfb640113e8be2f5d25034f5657a9609ee06082b817dc24116c5e1d7a708ca31e8eedcc47f7d309def2ce63be662d1d0a37a1c7bdc7345968a31d04c0a2377 + "@typescript-eslint/types": "npm:8.10.0" + "@typescript-eslint/visitor-keys": "npm:8.10.0" + checksum: 10/02cf2afc57bd048639d876030f6826e7b522bf36db40b7dd7b8e1b8c6f853e8c41b41044b7a32f118bac1b721aff4dfe660d5891e0a9ee103ef87c5ee1792b4c languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.9.0": - version: 8.9.0 - resolution: "@typescript-eslint/type-utils@npm:8.9.0" +"@typescript-eslint/type-utils@npm:8.10.0": + version: 8.10.0 + resolution: "@typescript-eslint/type-utils@npm:8.10.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:8.9.0" - "@typescript-eslint/utils": "npm:8.9.0" + "@typescript-eslint/typescript-estree": "npm:8.10.0" + "@typescript-eslint/utils": "npm:8.10.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.3.0" peerDependenciesMeta: typescript: optional: true - checksum: 10/aaeb465ed57d140bc0d9a8b81a474eff5d1c63d99479828b4eb83a1a626dcb2b1377052a971be5b4d094d6adcf1cf8e33c41ee13369bd71aed0f9cd9f3528c8a + checksum: 10/d173232b8bb1738eeb107a76d6e8b5afdfa97b62bff23db22f8a132db01c560b7d9c2c658e3c2bdccd2e7f5dfdf75ddb70d362a44d713a8c7bacdd56e29fd2ee languageName: node linkType: hard -"@typescript-eslint/types@npm:8.9.0": - version: 8.9.0 - resolution: "@typescript-eslint/types@npm:8.9.0" - checksum: 10/4d087153605ec23c980f9bc807b122edefff828e0c3b52ef531f4b8e1d30078c39f95e84019370a395bf97eed0d7886cc50b8cd545c287f8a2a21b301272377a +"@typescript-eslint/types@npm:8.10.0": + version: 8.10.0 + resolution: "@typescript-eslint/types@npm:8.10.0" + checksum: 10/2701711c87181553b68cdeba9d8ea55e0ae8ac441b5fe9667ee8be1dbac20386698930239a0e210b73d14961110ab128559a162abaed6e890a851543b6617c97 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.9.0": - version: 8.9.0 - resolution: "@typescript-eslint/typescript-estree@npm:8.9.0" +"@typescript-eslint/typescript-estree@npm:8.10.0": + version: 8.10.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.10.0" dependencies: - "@typescript-eslint/types": "npm:8.9.0" - "@typescript-eslint/visitor-keys": "npm:8.9.0" + "@typescript-eslint/types": "npm:8.10.0" + "@typescript-eslint/visitor-keys": "npm:8.10.0" debug: "npm:^4.3.4" fast-glob: "npm:^3.3.2" is-glob: "npm:^4.0.3" @@ -2377,31 +2425,31 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/855b433f24fad5d6791c16510d035ded31ccfd17235b45f4dcb7fa89ed57268e4bf4bf79311c5323037e6243da506b2edcb113aa51339291efb344b6d8035b1a + checksum: 10/7513fbc43a0d5f06f45e20d18b6855a3e52bd4124283a4b704bb53c6d2c7edfa783cd4fa2c35217bf8562a6bc80892067fa4780aec97d99580624cbd05cde471 languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.9.0": - version: 8.9.0 - resolution: "@typescript-eslint/utils@npm:8.9.0" +"@typescript-eslint/utils@npm:8.10.0": + version: 8.10.0 + resolution: "@typescript-eslint/utils@npm:8.10.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:8.9.0" - "@typescript-eslint/types": "npm:8.9.0" - "@typescript-eslint/typescript-estree": "npm:8.9.0" + "@typescript-eslint/scope-manager": "npm:8.10.0" + "@typescript-eslint/types": "npm:8.10.0" + "@typescript-eslint/typescript-estree": "npm:8.10.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - checksum: 10/84efd10d6aa212103615cf52211a79f1ca02dc4fbf2dbb3a8d2aa49cd19f582b04c219ee98ed1ab77a503f967d82ce56521b1663359ff3e7faaa1f8798c19697 + checksum: 10/a28f9fbec67b92bfb9c58445f9cfeb3208d48ecfda4c3ce649e70291af1d23a05466ce76bae9f6aff1270f40a434c8b6a7a71267108b6c32b1c059758f879cc0 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.9.0": - version: 8.9.0 - resolution: "@typescript-eslint/visitor-keys@npm:8.9.0" +"@typescript-eslint/visitor-keys@npm:8.10.0": + version: 8.10.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.10.0" dependencies: - "@typescript-eslint/types": "npm:8.9.0" + "@typescript-eslint/types": "npm:8.10.0" eslint-visitor-keys: "npm:^3.4.3" - checksum: 10/809097884b8c706f549d99bafa3e0958bd893b3deb190297110f2f1f9360e12064335c8f2df68f39be7d744d2032b5eb57b710c9671eb38f793877ab9364c731 + checksum: 10/637d4f2a812e5dcf12b2342ebb296fda5e87e425430623c31660d60e09f87fc8dc9843cc0d9b81fe4963e25ce9a44a4418e8b7878b73773f4c1375fb68006b16 languageName: node linkType: hard @@ -2520,22 +2568,32 @@ __metadata: languageName: node linkType: hard -"@xmtp/consent-proof-signature@npm:^0.1.3": - version: 0.1.3 - resolution: "@xmtp/consent-proof-signature@npm:0.1.3" +"@xmtp/consent-proof-signature@npm:^0.1.3, @xmtp/consent-proof-signature@workspace:packages/consent-proof-signature": + version: 0.0.0-use.local + resolution: "@xmtp/consent-proof-signature@workspace:packages/consent-proof-signature" dependencies: - "@xmtp/proto": "npm:3.56.0" + "@rollup/plugin-terser": "npm:^0.4.4" + "@rollup/plugin-typescript": "npm:^12.1.1" + "@xmtp/proto": "npm:3.62.1" + ethers: "npm:^6.13.1" long: "npm:^5.2.3" - checksum: 10/24f3c5298a951cbf561c7986ffba670400560b94ce51f1ace5b29f98c899c554e13f01b370752e2a9159ccb885d7a0031e75f6d96816c81d799df877bd59715f - languageName: node - linkType: hard + rollup: "npm:^4.24.0" + rollup-plugin-dts: "npm:^6.1.1" + rollup-plugin-filesize: "npm:^10.0.0" + tsconfig: "workspace:*" + typedoc: "npm:^0.26.4" + typescript: "npm:^5.6.3" + vite: "npm:^5.4.9" + vitest: "npm:^2.1.3" + languageName: unknown + linkType: soft "@xmtp/content-type-primitives@npm:^1.0.1, @xmtp/content-type-primitives@npm:^1.0.2, @xmtp/content-type-primitives@workspace:content-types/content-type-primitives": version: 0.0.0-use.local resolution: "@xmtp/content-type-primitives@workspace:content-types/content-type-primitives" dependencies: "@rollup/plugin-terser": "npm:^0.4.4" - "@rollup/plugin-typescript": "npm:^12.1.0" + "@rollup/plugin-typescript": "npm:^12.1.1" "@types/node": "npm:^20.16.11" "@xmtp/proto": "npm:^3.61.1" happy-dom: "npm:^15.7.4" @@ -2554,7 +2612,7 @@ __metadata: resolution: "@xmtp/content-type-reaction@workspace:content-types/content-type-reaction" dependencies: "@rollup/plugin-terser": "npm:^0.4.4" - "@rollup/plugin-typescript": "npm:^12.1.0" + "@rollup/plugin-typescript": "npm:^12.1.1" "@types/node": "npm:^20.16.11" "@xmtp/content-type-primitives": "npm:^1.0.2" "@xmtp/xmtp-js": "npm:^11.6.3" @@ -2576,7 +2634,7 @@ __metadata: resolution: "@xmtp/content-type-read-receipt@workspace:content-types/content-type-read-receipt" dependencies: "@rollup/plugin-terser": "npm:^0.4.4" - "@rollup/plugin-typescript": "npm:^12.1.0" + "@rollup/plugin-typescript": "npm:^12.1.1" "@types/node": "npm:^20.16.11" "@xmtp/content-type-primitives": "npm:^1.0.2" "@xmtp/xmtp-js": "npm:^11.6.3" @@ -2600,7 +2658,7 @@ __metadata: "@noble/secp256k1": "npm:^1.7.1" "@rollup/plugin-node-resolve": "npm:^15.3.0" "@rollup/plugin-terser": "npm:^0.4.4" - "@rollup/plugin-typescript": "npm:^12.1.0" + "@rollup/plugin-typescript": "npm:^12.1.1" "@types/node": "npm:^20.16.11" "@xmtp/content-type-primitives": "npm:^1.0.2" "@xmtp/encryption": "workspace:*" @@ -2625,7 +2683,7 @@ __metadata: resolution: "@xmtp/content-type-reply@workspace:content-types/content-type-reply" dependencies: "@rollup/plugin-terser": "npm:^0.4.4" - "@rollup/plugin-typescript": "npm:^12.1.0" + "@rollup/plugin-typescript": "npm:^12.1.1" "@types/node": "npm:^20.16.11" "@xmtp/content-type-primitives": "npm:^1.0.2" "@xmtp/content-type-remote-attachment": "workspace:*" @@ -2649,7 +2707,7 @@ __metadata: resolution: "@xmtp/content-type-text@workspace:content-types/content-type-text" dependencies: "@rollup/plugin-terser": "npm:^0.4.4" - "@rollup/plugin-typescript": "npm:^12.1.0" + "@rollup/plugin-typescript": "npm:^12.1.1" "@types/node": "npm:^20.16.11" "@xmtp/content-type-primitives": "npm:^1.0.1" "@xmtp/xmtp-js": "npm:^11.6.3" @@ -2671,7 +2729,7 @@ __metadata: resolution: "@xmtp/content-type-transaction-reference@workspace:content-types/content-type-transaction-reference" dependencies: "@rollup/plugin-terser": "npm:^0.4.4" - "@rollup/plugin-typescript": "npm:^12.1.0" + "@rollup/plugin-typescript": "npm:^12.1.1" "@types/node": "npm:^20.16.11" "@xmtp/content-type-primitives": "npm:^1.0.1" "@xmtp/xmtp-js": "npm:^11.6.3" @@ -2693,7 +2751,7 @@ __metadata: resolution: "@xmtp/encryption@workspace:shared/encryption" dependencies: "@rollup/plugin-terser": "npm:^0.4.4" - "@rollup/plugin-typescript": "npm:^12.1.0" + "@rollup/plugin-typescript": "npm:^12.1.1" "@types/node": "npm:^20.16.11" "@vitest/coverage-v8": "npm:^2.1.3" "@xmtp/proto": "npm:^3.68.0" @@ -2711,6 +2769,34 @@ __metadata: languageName: unknown linkType: soft +"@xmtp/frames-client@workspace:packages/frames-client": + version: 0.0.0-use.local + resolution: "@xmtp/frames-client@workspace:packages/frames-client" + dependencies: + "@noble/hashes": "npm:^1.4.0" + "@open-frames/proxy-client": "npm:^0.3.3" + "@open-frames/types": "npm:^0.1.1" + "@rollup/plugin-terser": "npm:^0.4.4" + "@rollup/plugin-typescript": "npm:^12.1.1" + "@xmtp/proto": "npm:3.62.1" + "@xmtp/xmtp-js": "npm:^12.0.0" + ethers: "npm:^6.13.1" + long: "npm:^5.2.3" + rollup: "npm:^4.24.0" + rollup-plugin-dts: "npm:^6.1.1" + rollup-plugin-filesize: "npm:^10.0.0" + rollup-plugin-tsconfig-paths: "npm:^1.5.2" + tsconfig: "workspace:*" + typedoc: "npm:^0.26.4" + typescript: "npm:^5.6.3" + vite: "npm:^5.4.9" + vite-tsconfig-paths: "npm:^5.0.1" + vitest: "npm:^2.1.3" + peerDependencies: + "@xmtp/xmtp-js": ">9.3.1" + languageName: unknown + linkType: soft + "@xmtp/node-bindings@npm:^0.0.13": version: 0.0.13 resolution: "@xmtp/node-bindings@npm:0.0.13" @@ -2723,7 +2809,7 @@ __metadata: resolution: "@xmtp/node-sdk@workspace:sdks/node-sdk" dependencies: "@rollup/plugin-json": "npm:^6.1.0" - "@rollup/plugin-typescript": "npm:^12.1.0" + "@rollup/plugin-typescript": "npm:^12.1.1" "@types/node": "npm:^20.16.11" "@vitest/coverage-v8": "npm:^2.1.3" "@xmtp/content-type-primitives": "npm:^1.0.1" @@ -2757,15 +2843,15 @@ __metadata: languageName: node linkType: hard -"@xmtp/proto@npm:3.56.0": - version: 3.56.0 - resolution: "@xmtp/proto@npm:3.56.0" +"@xmtp/proto@npm:3.62.1": + version: 3.62.1 + resolution: "@xmtp/proto@npm:3.62.1" dependencies: long: "npm:^5.2.0" protobufjs: "npm:^7.0.0" rxjs: "npm:^7.8.0" undici: "npm:^5.8.1" - checksum: 10/f752e6858692464319d6f22861fe8f23c46d9bb0eb390fe2220e0b4932a4de84be2e9e1cbafc0200e1bfe2a0ed3a3fb6079941630e57fb80e6325bc2a52bf10d + checksum: 10/7d6633f5ffb60725a6f3f128191944caf203fb3110a6076cdec31bc3cc6e5dca1b03170c6fa38b877125475ed3050031b93a47587c5e6bee6ebd91de53f8f0f2 languageName: node linkType: hard @@ -2817,6 +2903,24 @@ __metadata: languageName: node linkType: hard +"@xmtp/xmtp-js@npm:^12.0.0": + version: 12.1.0 + resolution: "@xmtp/xmtp-js@npm:12.1.0" + dependencies: + "@noble/secp256k1": "npm:1.7.1" + "@xmtp/consent-proof-signature": "npm:^0.1.3" + "@xmtp/content-type-primitives": "npm:^1.0.1" + "@xmtp/content-type-text": "npm:^1.0.0" + "@xmtp/proto": "npm:^3.62.1" + "@xmtp/user-preferences-bindings-wasm": "npm:^0.3.6" + async-mutex: "npm:^0.5.0" + elliptic: "npm:^6.5.5" + long: "npm:^5.2.3" + viem: "npm:2.7.15" + checksum: 10/4368b9e7f9fb6a6b4dd63110e655ef41d9c5aabf8666c0a9f0d166e31d1f3cde1af9bd6c981d620c81b8a0466ac612195007bbb9342142da39ee1b4ff75e1adb + languageName: node + linkType: hard + "@xmtp/xmtp-js@workspace:^, @xmtp/xmtp-js@workspace:sdks/js-sdk": version: 0.0.0-use.local resolution: "@xmtp/xmtp-js@workspace:sdks/js-sdk" @@ -2826,7 +2930,7 @@ __metadata: "@rollup/plugin-json": "npm:^6.1.0" "@rollup/plugin-node-resolve": "npm:^15.3.0" "@rollup/plugin-terser": "npm:^0.4.4" - "@rollup/plugin-typescript": "npm:^12.1.0" + "@rollup/plugin-typescript": "npm:^12.1.1" "@types/benchmark": "npm:^2.1.5" "@types/bl": "npm:^5.1.0" "@types/callback-to-async-iterator": "npm:^1.1.7" @@ -2922,7 +3026,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.12.0": +"acorn@npm:^8.12.0, acorn@npm:^8.8.2": version: 8.13.0 resolution: "acorn@npm:8.13.0" bin: @@ -2931,15 +3035,6 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.8.2": - version: 8.12.1 - resolution: "acorn@npm:8.12.1" - bin: - acorn: bin/acorn - checksum: 10/d08c2d122bba32d0861e0aa840b2ee25946c286d5dc5990abca991baf8cdbfbe199b05aacb221b979411a2fea36f83e26b5ac4f6b4e0ce49038c62316c1848f0 - languageName: node - linkType: hard - "aes-js@npm:3.0.0": version: 3.0.0 resolution: "aes-js@npm:3.0.0" @@ -3392,9 +3487,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.30001663": - version: 1.0.30001667 - resolution: "caniuse-lite@npm:1.0.30001667" - checksum: 10/5f0c48abb806737c422f05d0d9dda72facc25ee8adbae2c2ea9c57b87d9c2fa9ad8c3f6d54f21aca4e31ee1742cb5dd1543bf6b9133e3f77f79a645876322414 + version: 1.0.30001669 + resolution: "caniuse-lite@npm:1.0.30001669" + checksum: 10/cd0b481bb997703cb7651e55666b4aa4e7b4ecf9784796e2393179a15e55c71a6abc6ff865c922bbd3bbfa4a4bf0530d8da13989b97ff8c7850c8a5bd4e00491 languageName: node linkType: hard @@ -3747,9 +3842,9 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.5.28": - version: 1.5.35 - resolution: "electron-to-chromium@npm:1.5.35" - checksum: 10/fe8cf5f1ec8587bbd256ddede11272808dd25cdef9d06d546c66495364e03463e9a3b664bf11ec077c1dbc91114dbeb52802b01d944e57ce922112d00b722a74 + version: 1.5.41 + resolution: "electron-to-chromium@npm:1.5.41" + checksum: 10/74e1773d954ddbea82036715f91d2ef78246c9747ac58c00efa4eae3957a29a86b9ef41adfd1a33b5e563cecfc587ad90d0b513673fce65f505af6f2e90e1777 languageName: node linkType: hard @@ -3768,7 +3863,7 @@ __metadata: languageName: node linkType: hard -"elliptic@npm:^6.5.4, elliptic@npm:^6.5.7": +"elliptic@npm:^6.5.4, elliptic@npm:^6.5.5, elliptic@npm:^6.5.7": version: 6.5.7 resolution: "elliptic@npm:6.5.7" dependencies: @@ -4162,18 +4257,18 @@ __metadata: languageName: node linkType: hard -"ethers@npm:^6.11.1": - version: 6.13.3 - resolution: "ethers@npm:6.13.3" +"ethers@npm:^6.11.1, ethers@npm:^6.13.1": + version: 6.13.4 + resolution: "ethers@npm:6.13.4" dependencies: "@adraffy/ens-normalize": "npm:1.10.1" "@noble/curves": "npm:1.2.0" "@noble/hashes": "npm:1.3.2" - "@types/node": "npm:18.15.13" + "@types/node": "npm:22.7.5" aes-js: "npm:4.0.0-beta.5" - tslib: "npm:2.4.0" + tslib: "npm:2.7.0" ws: "npm:8.17.1" - checksum: 10/a3b11a5bd97269f2aa5e5cb844642a84fe139a188fd3c0d7d0c4c7b4958d56286e84c14cd41d1c53bd5dff8bf1060c73bd7a9bde8313f8a994d94881f4010037 + checksum: 10/221192fed93f6b0553f3e5e72bfd667d676220577d34ff854f677e955d6f608e60636a9c08b5d54039c532a9b9b7056384f0d7019eb6e111d53175806f896ac6 languageName: node linkType: hard @@ -5394,11 +5489,11 @@ __metadata: linkType: hard "magic-string@npm:^0.30.10, magic-string@npm:^0.30.11": - version: 0.30.11 - resolution: "magic-string@npm:0.30.11" + version: 0.30.12 + resolution: "magic-string@npm:0.30.12" dependencies: "@jridgewell/sourcemap-codec": "npm:^1.5.0" - checksum: 10/b784d2240252f5b1e755d487354ada4c672cbca16f045144f7185a75b059210e5fcca7be7be03ef1bac2ca754c4428b21d36ae64a9057ba429916f06b8c54eb2 + checksum: 10/98016180a52b28efc1362152b45671067facccdaead6b70c1c14c566cba98491bc2e1336474b0996397730dca24400e85649da84d3da62b2560ed03c067573e6 languageName: node linkType: hard @@ -6252,9 +6347,9 @@ __metadata: linkType: hard "picocolors@npm:^1.0.0, picocolors@npm:^1.1.0": - version: 1.1.0 - resolution: "picocolors@npm:1.1.0" - checksum: 10/a2ad60d94d185c30f2a140b19c512547713fb89b920d32cc6cf658fa786d63a37ba7b8451872c3d9fc34883971fb6e5878e07a20b60506e0bb2554dce9169ccb + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: 10/e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 languageName: node linkType: hard @@ -7222,8 +7317,8 @@ __metadata: linkType: hard "terser@npm:^5.17.4, terser@npm:^5.6.0": - version: 5.34.1 - resolution: "terser@npm:5.34.1" + version: 5.36.0 + resolution: "terser@npm:5.36.0" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.8.2" @@ -7231,7 +7326,7 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10/4389f39b5b841e2a7795ee733b54bf8fc44f8784a78c213dae32c7e6adc66c3bb258ebdcbacb8e7f1fa08fceb20bfc4ce4f7666d42bbfc29ab71126e89614c34 + checksum: 10/52e641419f79d7ccdecd136b9a8e0b03f93cfe3b53cce556253aaabc347d3f2af1745419b9e622abc95d592084dc76e57774b8f9e68d29d543f4dd11c044daf4 languageName: node linkType: hard @@ -7261,9 +7356,9 @@ __metadata: linkType: hard "tinyexec@npm:^0.3.0": - version: 0.3.0 - resolution: "tinyexec@npm:0.3.0" - checksum: 10/317cc536d091ce7e50271287798d91ef53c4dc80088844d890752a2c7387d213004cba83e5e1d9129390ced617625e34f4a8f0ba5779e31c9b6939f9be0d3543 + version: 0.3.1 + resolution: "tinyexec@npm:0.3.1" + checksum: 10/0537c70590d52d354f40c0255ff0f654a3d18ddb3812b440ddf9d436edf516c8057838ad5a38744c0c59670ec03e3cf23fbe04ae3d49f031d948274e99002569 languageName: node linkType: hard @@ -7330,8 +7425,8 @@ __metadata: linkType: hard "tsconfck@npm:^3.0.3": - version: 3.1.3 - resolution: "tsconfck@npm:3.1.3" + version: 3.1.4 + resolution: "tsconfck@npm:3.1.4" peerDependencies: typescript: ^5.0.0 peerDependenciesMeta: @@ -7339,27 +7434,27 @@ __metadata: optional: true bin: tsconfck: bin/tsconfck.js - checksum: 10/bf9b9b72de5b83f833f5dea8b276e77bab08e85751589f36dd23854fa3d5f7955194086fb8424df388bf232f2fc9a067d7913bfa674cb1217be0bba648ec71f2 + checksum: 10/4fb02e75ff374a82052b4800970bebe4466b5a6e7193d74e7b875cc8225acb5037fb4e7dcd4a5cd751c22129360cb13b4d5536897eae131d69c1a20fb18a99b4 languageName: node linkType: hard -"tsconfig@workspace:shared/tsconfig": +"tsconfig@workspace:*, tsconfig@workspace:shared/tsconfig": version: 0.0.0-use.local resolution: "tsconfig@workspace:shared/tsconfig" languageName: unknown linkType: soft -"tslib@npm:2.4.0": - version: 2.4.0 - resolution: "tslib@npm:2.4.0" - checksum: 10/d8379e68b36caf082c1905ec25d17df8261e1d68ddc1abfd6c91158a064f6e4402039ae7c02cf4c81d12e3a2a2c7cd8ea2f57b233eb80136a2e3e7279daf2911 +"tslib@npm:2.7.0": + version: 2.7.0 + resolution: "tslib@npm:2.7.0" + checksum: 10/9a5b47ddac65874fa011c20ff76db69f97cf90c78cff5934799ab8894a5342db2d17b4e7613a087046bc1d133d21547ddff87ac558abeec31ffa929c88b7fce6 languageName: node linkType: hard "tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2": - version: 2.7.0 - resolution: "tslib@npm:2.7.0" - checksum: 10/9a5b47ddac65874fa011c20ff76db69f97cf90c78cff5934799ab8894a5342db2d17b4e7613a087046bc1d133d21547ddff87ac558abeec31ffa929c88b7fce6 + version: 2.8.0 + resolution: "tslib@npm:2.8.0" + checksum: 10/1bc7c43937477059b4d26f2dbde7e49ef0fb4f38f3014e0603eaea76d6a885742c8b1762af45949145e5e7408a736d20ded949da99dabc8ccba1fc5531d2d927 languageName: node linkType: hard @@ -7468,9 +7563,9 @@ __metadata: languageName: node linkType: hard -"typedoc@npm:^0.26.8": - version: 0.26.8 - resolution: "typedoc@npm:0.26.8" +"typedoc@npm:^0.26.4, typedoc@npm:^0.26.8": + version: 0.26.10 + resolution: "typedoc@npm:0.26.10" dependencies: lunr: "npm:^2.3.9" markdown-it: "npm:^14.1.0" @@ -7481,21 +7576,21 @@ __metadata: typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x bin: typedoc: bin/typedoc - checksum: 10/a903e77fdbc45f8fa99c6454f31d36304b9edcd4f04a787bed25f0300ce779ffebfd9dc8525678484799bc2d0990bc40522a222f962a4f65a079e68950d13670 + checksum: 10/22db2da44fe06274b0b6620570802baf6cefca931fca8eadbdb3ca51b1fca7c5561d0689ae73c6763cfc7aa554079a26f200b436a4d5848a7bf3ceb2aa205340 languageName: node linkType: hard -"typescript-eslint@npm:^8.9.0": - version: 8.9.0 - resolution: "typescript-eslint@npm:8.9.0" +"typescript-eslint@npm:^8.10.0": + version: 8.10.0 + resolution: "typescript-eslint@npm:8.10.0" dependencies: - "@typescript-eslint/eslint-plugin": "npm:8.9.0" - "@typescript-eslint/parser": "npm:8.9.0" - "@typescript-eslint/utils": "npm:8.9.0" + "@typescript-eslint/eslint-plugin": "npm:8.10.0" + "@typescript-eslint/parser": "npm:8.10.0" + "@typescript-eslint/utils": "npm:8.10.0" peerDependenciesMeta: typescript: optional: true - checksum: 10/34ec65b9f3b9b2a8a17e02bf85c3eab1b9c8a1ccd51883038a2e69f8064177de68916b92976d3b1fe96e52c95898e0de204f43269b76e2230fbefad41cf9b061 + checksum: 10/e59e5bd486155363d66ff2dc5cf81a58a4f40172286bd15ad5f00481cc3dee53837f14ead68dad2e65727c826b17a53424e6325b84bc0a9353337ff0c937b264 languageName: node linkType: hard @@ -7754,8 +7849,8 @@ __metadata: linkType: hard "viem@npm:^2.13.6": - version: 2.21.21 - resolution: "viem@npm:2.21.21" + version: 2.21.28 + resolution: "viem@npm:2.21.28" dependencies: "@adraffy/ens-normalize": "npm:1.11.0" "@noble/curves": "npm:1.6.0" @@ -7771,7 +7866,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/1fe36236c802a512a359c4710d98e627c04795cdf62bb0341c9ac6ab8afc5626431a1b471062ac29f5e2f23bca6ce933d552858f55ad1968514aaea1fb74324d + checksum: 10/191b97d26afa587297f3d940d6ee8e2724944ddd0beae417d235412dedeeef35247b2c02d5ae38904066151378101f0a271557d79625711c1c0ce155e9c8e88f languageName: node linkType: hard @@ -7805,50 +7900,7 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.0.0": - version: 5.4.8 - resolution: "vite@npm:5.4.8" - dependencies: - esbuild: "npm:^0.21.3" - fsevents: "npm:~2.3.3" - postcss: "npm:^8.4.43" - rollup: "npm:^4.20.0" - peerDependencies: - "@types/node": ^18.0.0 || >=20.0.0 - less: "*" - lightningcss: ^1.21.0 - sass: "*" - sass-embedded: "*" - stylus: "*" - sugarss: "*" - terser: ^5.4.0 - dependenciesMeta: - fsevents: - optional: true - peerDependenciesMeta: - "@types/node": - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - bin: - vite: bin/vite.js - checksum: 10/17fdffa558abaf854f04ead7d3ddd76e4556a59871f9ac63cca3fc20a79979984837d8dddaae4b171e3d73061f781e4eec0f6d3babdbce2b4d111d29cf474c1c - languageName: node - linkType: hard - -"vite@npm:^5.4.9": +"vite@npm:^5.0.0, vite@npm:^5.4.9": version: 5.4.9 resolution: "vite@npm:5.4.9" dependencies: @@ -8165,7 +8217,7 @@ __metadata: rimraf: "npm:^6.0.1" turbo: "npm:^2.1.3" typescript: "npm:^5.6.3" - typescript-eslint: "npm:^8.9.0" + typescript-eslint: "npm:^8.10.0" languageName: unknown linkType: soft @@ -8191,11 +8243,11 @@ __metadata: linkType: hard "yaml@npm:^2.5.1": - version: 2.5.1 - resolution: "yaml@npm:2.5.1" + version: 2.6.0 + resolution: "yaml@npm:2.6.0" bin: yaml: bin.mjs - checksum: 10/0eecb679db75ea6a989ad97715a9fa5d946972945aa6aa7d2175bca66c213b5564502ccb1cdd04b1bf816ee38b5c43e4e2fda3ff6f5e09da24dabb51ae92c57d + checksum: 10/f4369f667c7626c216ea81b5840fe9b530cdae4cff2d84d166ec1239e54bf332dbfac4a71bf60d121f8e85e175364a4e280a520292269b6cf9d074368309adf9 languageName: node linkType: hard