From 635c729e2068353efdd21fd90c098de349329b8c Mon Sep 17 00:00:00 2001 From: Stephan Cilliers <5469870+stephancill@users.noreply.github.com> Date: Thu, 25 Jan 2024 16:51:34 +0200 Subject: [PATCH 1/4] fix(core): deprecate ENS support in `ModManifest` `custodyAddress` field --- .changeset/slow-goats-share.md | 18 ++++++++++++++++++ mods/chatgpt-shorten/src/manifest.ts | 2 +- mods/chatgpt/src/manifest.ts | 2 +- mods/dall-e/src/manifest.ts | 2 +- mods/giphy-picker/src/manifest.ts | 2 +- mods/image-render/src/manifest.ts | 2 +- mods/imgur-upload/src/manifest.ts | 2 +- mods/infura-ipfs-upload/src/manifest.ts | 2 +- mods/livepeer-video/src/manifest.ts | 2 +- mods/nft-minter/src/manifest.ts | 2 +- mods/url-render/src/manifest.ts | 2 +- mods/video-render/src/manifest.ts | 2 +- mods/zora-create/src/manifest.ts | 2 +- mods/zora-nft-minter/src/manifest.ts | 2 +- packages/core/src/manifest.ts | 4 ++-- 15 files changed, 33 insertions(+), 15 deletions(-) create mode 100644 .changeset/slow-goats-share.md diff --git a/.changeset/slow-goats-share.md b/.changeset/slow-goats-share.md new file mode 100644 index 00000000..76b1fe56 --- /dev/null +++ b/.changeset/slow-goats-share.md @@ -0,0 +1,18 @@ +--- +"@mods/infura-ipfs-upload": patch +"@mods/chatgpt-shorten": patch +"@mods/zora-nft-minter": patch +"@mods/livepeer-video": patch +"@mods/giphy-picker": patch +"@mods/image-render": patch +"@mods/imgur-upload": patch +"@mods/video-render": patch +"@mods/zora-create": patch +"@mods/nft-minter": patch +"@mods/url-render": patch +"@mods/chatgpt": patch +"@mods/dall-e": patch +"@mod-protocol/core": minor +--- + +fix: deprecate ENS support for `ModManifest` `custodyAddress` field diff --git a/mods/chatgpt-shorten/src/manifest.ts b/mods/chatgpt-shorten/src/manifest.ts index 9b673bdb..cffd7975 100644 --- a/mods/chatgpt-shorten/src/manifest.ts +++ b/mods/chatgpt-shorten/src/manifest.ts @@ -7,7 +7,7 @@ import loading from "./loading"; const manifest: ModManifest = { slug: "chatgpt-shorten", name: "Shorten text using AI", - custodyAddress: "furlong.eth", + custodyAddress: "0xdcC59cF0Adf4175973D4abc8c0715f83f90d2f1d", logo: "https://i.imgur.com/hV566qC.png", custodyGithubUsername: "davidfurlong", version: "0.0.1", diff --git a/mods/chatgpt/src/manifest.ts b/mods/chatgpt/src/manifest.ts index 3bcbc0e8..7f83a29f 100644 --- a/mods/chatgpt/src/manifest.ts +++ b/mods/chatgpt/src/manifest.ts @@ -7,7 +7,7 @@ import loading from "./loading"; const manifest: ModManifest = { slug: "chatgpt", name: "Prompt ChatGPT", - custodyAddress: "furlong.eth", + custodyAddress: "0xdcC59cF0Adf4175973D4abc8c0715f83f90d2f1d", logo: "https://i.imgur.com/YayIWi1.png", custodyGithubUsername: "davidfurlong", version: "0.0.1", diff --git a/mods/dall-e/src/manifest.ts b/mods/dall-e/src/manifest.ts index da95fbbc..9eb86a69 100644 --- a/mods/dall-e/src/manifest.ts +++ b/mods/dall-e/src/manifest.ts @@ -7,7 +7,7 @@ import loading from "./loading"; const manifest: ModManifest = { slug: "dall-e", name: "Use AI to make an image", - custodyAddress: "furlong.eth", + custodyAddress: "0xdcC59cF0Adf4175973D4abc8c0715f83f90d2f1d", logo: "https://i.imgur.com/zKiFDal.png", custodyGithubUsername: "davidfurlong", version: "0.0.1", diff --git a/mods/giphy-picker/src/manifest.ts b/mods/giphy-picker/src/manifest.ts index 314343ba..e9116768 100644 --- a/mods/giphy-picker/src/manifest.ts +++ b/mods/giphy-picker/src/manifest.ts @@ -7,7 +7,7 @@ import loading from "./loading"; const manifest: ModManifest = { slug: "giphy-picker", name: "Add GIF/Sticker", - custodyAddress: "furlong.eth", + custodyAddress: "0xdcC59cF0Adf4175973D4abc8c0715f83f90d2f1d", custodyGithubUsername: "davidfurlong", logo: "https://i.imgur.com/vccxL2r.png", version: "0.0.1", diff --git a/mods/image-render/src/manifest.ts b/mods/image-render/src/manifest.ts index 7d4ce176..f4ee470e 100644 --- a/mods/image-render/src/manifest.ts +++ b/mods/image-render/src/manifest.ts @@ -4,7 +4,7 @@ import view from "./view"; const manifest: ModManifest = { slug: "image-render", name: "View Images", - custodyAddress: "furlong.eth", + custodyAddress: "0xdcC59cF0Adf4175973D4abc8c0715f83f90d2f1d", version: "0.0.1", logo: "https://i.imgur.com/75cFuT9.png", custodyGithubUsername: "davidfurlong", diff --git a/mods/imgur-upload/src/manifest.ts b/mods/imgur-upload/src/manifest.ts index f97c66b8..4e9d40cd 100644 --- a/mods/imgur-upload/src/manifest.ts +++ b/mods/imgur-upload/src/manifest.ts @@ -7,7 +7,7 @@ import upload from "./upload"; const manifest: ModManifest = { slug: "imgur-upload", name: "Upload image to Imgur", - custodyAddress: "stephancill.eth", + custodyAddress: "0xdcC59cF0Adf4175973D4abc8c0715f83f90d2f1d", logo: "https://imgur.com/favicon.ico", custodyGithubUsername: "stephancill", version: "0.0.1", diff --git a/mods/infura-ipfs-upload/src/manifest.ts b/mods/infura-ipfs-upload/src/manifest.ts index ce27a289..45c31ea0 100644 --- a/mods/infura-ipfs-upload/src/manifest.ts +++ b/mods/infura-ipfs-upload/src/manifest.ts @@ -7,7 +7,7 @@ import upload from "./upload"; const manifest: ModManifest = { slug: "infura-ipfs-upload", name: "Add image", - custodyAddress: "furlong.eth", + custodyAddress: "0xdcC59cF0Adf4175973D4abc8c0715f83f90d2f1d", logo: "https://i.imgur.com/FxgecX7.png", custodyGithubUsername: "davidfurlong", version: "0.0.1", diff --git a/mods/livepeer-video/src/manifest.ts b/mods/livepeer-video/src/manifest.ts index 480a2bd7..f19d6b9b 100644 --- a/mods/livepeer-video/src/manifest.ts +++ b/mods/livepeer-video/src/manifest.ts @@ -7,7 +7,7 @@ import upload from "./upload"; const manifest: ModManifest = { slug: "livepeer-video", name: "Add video", - custodyAddress: "furlong.eth", + custodyAddress: "0xdcC59cF0Adf4175973D4abc8c0715f83f90d2f1d", logo: "https://i.imgur.com/89epIn5.png", custodyGithubUsername: "davidfurlong", version: "0.0.1", diff --git a/mods/nft-minter/src/manifest.ts b/mods/nft-minter/src/manifest.ts index 56b10624..2b29ad00 100644 --- a/mods/nft-minter/src/manifest.ts +++ b/mods/nft-minter/src/manifest.ts @@ -4,7 +4,7 @@ import view from "./view"; const manifest: ModManifest = { slug: "nft-minter", name: "Preview and mint NFTs", - custodyAddress: "furlong.eth", + custodyAddress: "0xdcC59cF0Adf4175973D4abc8c0715f83f90d2f1d", version: "0.0.1", logo: "https://i.imgur.com/fuSkgoJ.png", custodyGithubUsername: "davidfurlong", diff --git a/mods/url-render/src/manifest.ts b/mods/url-render/src/manifest.ts index 0c7050bd..05ffa507 100644 --- a/mods/url-render/src/manifest.ts +++ b/mods/url-render/src/manifest.ts @@ -5,7 +5,7 @@ import fullimage from "./fullimage"; const manifest: ModManifest = { slug: "url-render", name: "View urls", - custodyAddress: "furlong.eth", + custodyAddress: "0xdcC59cF0Adf4175973D4abc8c0715f83f90d2f1d", version: "0.0.1", logo: "https://i.imgur.com/E7PAMHH.png", custodyGithubUsername: "davidfurlong", diff --git a/mods/video-render/src/manifest.ts b/mods/video-render/src/manifest.ts index aafe82f3..1c9347c6 100644 --- a/mods/video-render/src/manifest.ts +++ b/mods/video-render/src/manifest.ts @@ -4,7 +4,7 @@ import view from "./view"; const manifest: ModManifest = { slug: "video-render", name: "View Videos", - custodyAddress: "furlong.eth", + custodyAddress: "0xdcC59cF0Adf4175973D4abc8c0715f83f90d2f1d", version: "0.0.1", logo: "https://i.imgur.com/RITeKTW.png", custodyGithubUsername: "davidfurlong", diff --git a/mods/zora-create/src/manifest.ts b/mods/zora-create/src/manifest.ts index 2e9a01bc..a0cb5c38 100644 --- a/mods/zora-create/src/manifest.ts +++ b/mods/zora-create/src/manifest.ts @@ -6,7 +6,7 @@ import loading from "./loading"; const manifest: ModManifest = { slug: "zora-create", name: "Add NFT via Zora Premint", - custodyAddress: "stephancill.eth", + custodyAddress: "0xdcC59cF0Adf4175973D4abc8c0715f83f90d2f1d", logo: "https://i.imgur.com/rsfLOfD.png", custodyGithubUsername: "stephancill", version: "0.0.1", diff --git a/mods/zora-nft-minter/src/manifest.ts b/mods/zora-nft-minter/src/manifest.ts index 2e965e76..1612d9c0 100644 --- a/mods/zora-nft-minter/src/manifest.ts +++ b/mods/zora-nft-minter/src/manifest.ts @@ -4,7 +4,7 @@ import view from "./view"; const manifest: ModManifest = { slug: "zora-nft-minter", name: "Preview and mint Zora NFTs", - custodyAddress: "stephancill.eth", + custodyAddress: "0xdcC59cF0Adf4175973D4abc8c0715f83f90d2f1d", version: "0.0.1", logo: "https://i.imgur.com/fuSkgoJ.png", custodyGithubUsername: "stephancill", diff --git a/packages/core/src/manifest.ts b/packages/core/src/manifest.ts index 3e47b32c..56e05ec0 100644 --- a/packages/core/src/manifest.ts +++ b/packages/core/src/manifest.ts @@ -12,8 +12,8 @@ export type ModManifest = { name: string; /** A (temporary) github username to define as the owner */ custodyGithubUsername: string; - /** An ethereum address or ENS address to define as the owner */ - custodyAddress: string; + /** An ethereum address to define as the owner */ + custodyAddress: `0x${string}`; /** A valid url pointing to an image file, it should be a square */ logo: string; /** should be the same as the package version */ From 076831ccf5641f881dc94fe4b4d8a90be9f24bd7 Mon Sep 17 00:00:00 2001 From: Stephan Cilliers <5469870+stephancill@users.noreply.github.com> Date: Thu, 25 Jan 2024 16:52:25 +0200 Subject: [PATCH 2/4] feat(core+react): client and mod attribution in transactions --- .changeset/late-timers-hammer.md | 6 ++++++ packages/core/src/renderer.ts | 19 +++++++++++++++++-- packages/react/src/index.tsx | 19 +++++++++++++++---- 3 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 .changeset/late-timers-hammer.md diff --git a/.changeset/late-timers-hammer.md b/.changeset/late-timers-hammer.md new file mode 100644 index 00000000..79c398aa --- /dev/null +++ b/.changeset/late-timers-hammer.md @@ -0,0 +1,6 @@ +--- +"@mod-protocol/react": minor +"@mod-protocol/core": minor +--- + +feat: client and mod attribution in transactions diff --git a/packages/core/src/renderer.ts b/packages/core/src/renderer.ts index adce7deb..33112f30 100644 --- a/packages/core/src/renderer.ts +++ b/packages/core/src/renderer.ts @@ -161,12 +161,13 @@ export type ModElementRef = export type BaseContext = { user?: { wallet?: { - address?: string; + address?: `0x${string}`; }; farcaster?: { fid?: string; }; }; + clientReferralAddress?: `0x${string}`; }; export type CreationContext = BaseContext & { @@ -933,13 +934,27 @@ export class Renderer { case "SENDETHTRANSACTION": { const promise = new Promise((resolve) => { setTimeout(() => { + /* Populate attribution tags */ + const zeroAddress = "0000000000000000000000000000000000000000"; + const modTag = this.manifest.custodyAddress.startsWith("0x") + ? this.manifest.custodyAddress.slice(2) + : zeroAddress; + const clientTag = + this.context.clientReferralAddress?.slice(2) || zeroAddress; + let txData = this.replaceInlineContext(action.txData.data || ""); + // Check if data is hex and contains at least a function signature + // 4 hex bytes (8 chars) + '0x' = 10 chars + if (txData.startsWith("0x") && txData.length >= 10) { + txData = txData + modTag + clientTag; + } + this.onSendEthTransactionAction( { data: { from: this.replaceInlineContext(action.txData.from), to: this.replaceInlineContext(action.txData.to), value: this.replaceInlineContext(action.txData.value || "0"), - data: this.replaceInlineContext(action.txData.data || ""), + data: txData, }, chainId: this.replaceInlineContext(action.chainId), }, diff --git a/packages/react/src/index.tsx b/packages/react/src/index.tsx index 7a24b53f..1b62a8c0 100644 --- a/packages/react/src/index.tsx +++ b/packages/react/src/index.tsx @@ -453,8 +453,14 @@ export const CreationMod = ( const input = variant === "creation" ? props.input : ""; const context = React.useMemo( - () => ({ input, embeds: props.embeds, api: props.api, user: props.user }), - [input, props.api, props.embeds, props.user] + () => ({ + input, + embeds: props.embeds, + api: props.api, + user: props.user, + clientReferralAddress: props.clientReferralAddress, + }), + [input, props.api, props.embeds, props.user, props.clientReferralAddress] ); const [renderer] = React.useState( @@ -501,8 +507,13 @@ export const RenderMod = ( const forceRerender = useForceRerender(); const context = React.useMemo( - () => ({ embed: props.embed, api: props.api, user: props.user }), - [props.embed, props.api, props.user] + () => ({ + embed: props.embed, + api: props.api, + user: props.user, + clientReferralAddress: props.clientReferralAddress, + }), + [props.embed, props.api, props.user, props.clientReferralAddress] ); const [renderer] = React.useState( From d9c543188198c3adb74019bccaf1fe67e7875bab Mon Sep 17 00:00:00 2001 From: Stephan Cilliers <5469870+stephancill@users.noreply.github.com> Date: Fri, 26 Jan 2024 16:33:23 +0200 Subject: [PATCH 3/4] fix(examples/nextjs-shadcn): add `clientReferralAddress` --- examples/nextjs-shadcn/.env.example | 3 ++- examples/nextjs-shadcn/src/app/editor-example.tsx | 3 +++ examples/nextjs-shadcn/src/app/embeds.tsx | 3 +++ turbo.json | 3 ++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/nextjs-shadcn/.env.example b/examples/nextjs-shadcn/.env.example index ea582081..508544a9 100644 --- a/examples/nextjs-shadcn/.env.example +++ b/examples/nextjs-shadcn/.env.example @@ -2,4 +2,5 @@ NEXT_PUBLIC_API_URL="http://localhost:3001/api" NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID="" NEXT_PUBLIC_URL="http://localhost:3000" NEXT_PUBLIC_HOST="localhost:3000" -NEXT_PUBLIC_EXPERIMENTAL_MODS="false" \ No newline at end of file +NEXT_PUBLIC_EXPERIMENTAL_MODS="false" +NEXT_PUBLIC_CLIENT_REFERRAL_ADDRESS= \ No newline at end of file diff --git a/examples/nextjs-shadcn/src/app/editor-example.tsx b/examples/nextjs-shadcn/src/app/editor-example.tsx index ee89db34..a9fc2fcc 100644 --- a/examples/nextjs-shadcn/src/app/editor-example.tsx +++ b/examples/nextjs-shadcn/src/app/editor-example.tsx @@ -51,6 +51,8 @@ import { useExperimentalMods } from "./use-experimental-mods"; // Optionally replace with your API_URL here const API_URL = process.env.NEXT_PUBLIC_API_URL ?? "https://api.modprotocol.org/api"; +const CLIENT_REFERRAL_ADDRESS = process.env + .NEXT_PUBLIC_CLIENT_REFERRAL_ADDRESS as `0x${string}` | undefined; const getMentions = getFarcasterMentions(API_URL); const getChannels = getFarcasterChannels(API_URL); @@ -217,6 +219,7 @@ export default function EditorExample() { input={getText()} embeds={getEmbeds()} api={API_URL} + clientReferralAddress={CLIENT_REFERRAL_ADDRESS} user={user} variant="creation" manifest={currentMod} diff --git a/examples/nextjs-shadcn/src/app/embeds.tsx b/examples/nextjs-shadcn/src/app/embeds.tsx index c753175b..e10525fe 100644 --- a/examples/nextjs-shadcn/src/app/embeds.tsx +++ b/examples/nextjs-shadcn/src/app/embeds.tsx @@ -72,6 +72,9 @@ export function Embeds(props: { embeds: Array }) { address, }, }, + clientReferralAddress: process.env.NEXT_PUBLIC_CLIENT_REFERRAL_ADDRESS as + | `0x${string}` + | undefined, }; }, [address]); diff --git a/turbo.json b/turbo.json index 4d0611b9..6e8ff70f 100644 --- a/turbo.json +++ b/turbo.json @@ -39,6 +39,7 @@ "IMGUR_CLIENT_ID", "NEXT_PUBLIC_EXPERIMENTAL_MODS", "ZORA_ADMIN_PRIVATE_KEY", - "NFT_STORAGE_API_KEY" + "NFT_STORAGE_API_KEY", + "NEXT_PUBLIC_CLIENT_REFERRAL_ADDRESS" ] } \ No newline at end of file From 12a98ba3212fca38dd256996cadf71f46fe7c26e Mon Sep 17 00:00:00 2001 From: Stephan Cilliers <5469870+stephancill@users.noreply.github.com> Date: Mon, 29 Jan 2024 10:33:58 +0200 Subject: [PATCH 4/4] fix(core): check if mod tag is the correct length --- packages/core/src/renderer.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/core/src/renderer.ts b/packages/core/src/renderer.ts index 33112f30..454e3e7f 100644 --- a/packages/core/src/renderer.ts +++ b/packages/core/src/renderer.ts @@ -936,9 +936,11 @@ export class Renderer { setTimeout(() => { /* Populate attribution tags */ const zeroAddress = "0000000000000000000000000000000000000000"; - const modTag = this.manifest.custodyAddress.startsWith("0x") - ? this.manifest.custodyAddress.slice(2) - : zeroAddress; + const modTag = + this.manifest.custodyAddress.startsWith("0x") && + this.manifest.custodyAddress.length === 42 + ? this.manifest.custodyAddress.slice(2) + : zeroAddress; const clientTag = this.context.clientReferralAddress?.slice(2) || zeroAddress; let txData = this.replaceInlineContext(action.txData.data || "");