@notifi-network/notifi-react-wallet-target-plugin
Version:
The Wallet Target Plugin context provider for @notifi-network/notifi-react
271 lines (263 loc) • 8.73 kB
JavaScript
// lib/context/NotifiWalletTargetContext.tsx
import React2 from "react";
// lib/hooks/useXmtp.ts
import {
isUsingEvmBlockchain
} from "@notifi-network/notifi-frontend-client";
import { useClient } from "@xmtp/react-sdk";
import React from "react";
// lib/utils/xmtp.ts
var coinbaseEndpoint = "https://broadcast.coinbase.com/api/rpc";
var createCoinbaseNonce = async () => {
const { result } = await fetch(`${coinbaseEndpoint}/createNonce`, {
method: "POST"
}).then((v) => v.json());
return result?.nonce;
};
var subscribeCoinbaseMessaging = async (payload) => {
const response = await fetch(`${coinbaseEndpoint}/messaging/subscribe`, {
method: "POST",
body: JSON.stringify(payload),
headers: {
"Content-Type": "text/plain"
}
});
return await response.json();
};
// lib/utils/signature.ts
var getMessage = (address, senderAddress, nonce) => `Coinbase Wallet Messaging subscribe
Address: ${address}
Partner Address: ${senderAddress}
Nonce: ${nonce}`;
var reformatSignature = (signature) => {
if (!signature) return "";
let hexString = "0x";
Object.values(signature).forEach(
(v) => hexString += v.toString(16).padStart(2, "0")
);
return hexString;
};
// lib/hooks/useXmtp.ts
var useXmpt = (input) => {
const { walletWithSignParams } = input;
const [isLoading, setIsLoading] = React.useState(false);
const [error, setError] = React.useState(null);
const authMethod = walletWithSignParams.walletBlockchain === "OFF_CHAIN" ? walletWithSignParams.signIn : walletWithSignParams.signMessage;
const xmtp = useClient();
const getSignature = React.useCallback(
async (message) => {
if (walletWithSignParams.walletBlockchain === "OFF_CHAIN") {
setError(Error(".getSignature: ERROR - OFF_CHAIN is not supported"));
return ".getSignature: ERROR - OFF_CHAIN is not supported";
}
let signature = "";
if (typeof message === "string") {
const encoder = new TextEncoder();
message = encoder.encode(message);
}
if (isUsingEvmBlockchain(walletWithSignParams)) {
signature = await walletWithSignParams.signMessage(message);
} else {
setError(Error(".getSignature: ERROR - This chain is not supported"));
console.error(".getSignature: ERROR - This chain is not supported");
}
return reformatSignature(signature);
},
[authMethod]
);
const xmtpXip42Impl = React.useCallback(
async (senderAddress) => {
if (walletWithSignParams.walletBlockchain === "OFF_CHAIN") {
setError(Error(".getSignature: ERROR - OFF_CHAIN is not supported"));
return ".getSignature: ERROR - OFF_CHAIN is not supported";
}
const options = {
persistConversations: false,
env: "production"
};
const address = walletWithSignParams.walletPublicKey;
const signer = {
getAddress: () => {
return new Promise((resolve) => {
resolve(address);
});
},
signMessage: async (message) => {
return getSignature(message);
}
};
const client = await xmtp.initialize({ options, signer });
if (!client) {
throw Error(
"xmtpXip42Impl: ERROR - XMTP client is uninitialized. Please try again."
);
}
const conversation = await client.conversations.newConversation(senderAddress);
await client.contacts.allow([senderAddress]);
return conversation.topic.split("/")[3];
},
[xmtp, getSignature]
);
const signCoinbaseSignature = React.useCallback(
async (frontendClient, web3TargetId, senderAddress) => {
if (walletWithSignParams.walletBlockchain === "OFF_CHAIN") {
setError(Error(".getSignature: ERROR - OFF_CHAIN is not supported"));
return;
}
setIsLoading(true);
try {
const conversationTopic = await xmtpXip42Impl(senderAddress);
if (!conversationTopic)
throw Error("Unable to get the conversation topic");
const address = walletWithSignParams.walletPublicKey;
const nonce = await createCoinbaseNonce();
const message = getMessage(address, senderAddress, nonce);
const signature = await getSignature(message);
if (!signature)
throw Error("Unable to sign the wallet. Please try again.");
const payload = {
address,
nonce,
signature,
isActivatedViaCb: true,
partnerAddress: senderAddress,
conversationTopic
};
await subscribeCoinbaseMessaging(payload);
const walletVerifyResult = await frontendClient.verifyXmtpTargetViaXip42({
input: {
web3TargetId,
accountId: address,
conversationTopic
}
});
return walletVerifyResult.verifyXmtpTargetViaXip42.web3Target;
} catch (e) {
console.error(".signCoinbaseSignature: ERROR - ", e);
setError(
e instanceof Error ? {
...e,
message: ".signCoinbaseSignature: ERROR - " + e.message
} : Error(".signCoinbaseSignature: ERROR - please try again.")
);
return;
} finally {
setIsLoading(false);
}
},
[xmtpXip42Impl]
);
return {
isLoading,
error,
signCoinbaseSignature
};
};
// lib/context/NotifiWalletTargetContext.tsx
import { jsx } from "react/jsx-runtime";
var NotifiWalletTargetContext = React2.createContext({
isLoading: false,
error: null,
signCoinbaseSignature: async () => {
console.error(
"NotifiWalletTargetProvider: ERROR - signCoinbaseSignature not implemented"
);
return void 0;
}
});
var NotifiWalletTargetContextProvider = ({ children, walletWithSignParams }) => {
const contextValue = useXmpt({
walletWithSignParams
});
return /* @__PURE__ */ jsx(NotifiWalletTargetContext.Provider, { value: contextValue, children });
};
var useWalletTargetContext = () => React2.useContext(NotifiWalletTargetContext);
// lib/context/NotifiContextProviderWithWalletTargetPlugin.tsx
import {
NotifiFrontendClientContextProvider,
NotifiHistoryContextProvider,
NotifiTargetContextProvider,
NotifiTenantConfigContextProvider,
NotifiTopicContextProvider,
NotifiUserSettingContextProvider
} from "@notifi-network/notifi-react";
// ../notifi-react/lib/context/GlobalStateContext.tsx
import {
createContext,
useContext,
useState
} from "react";
import { jsx as jsx2 } from "react/jsx-runtime";
var GlobalStateContext = createContext({
globalLoading: { isLoading: false },
setGlobalLoading: () => void 0,
globalError: null,
setGlobalError: () => void 0,
globalCtas: null,
setGlobalCtas: () => void 0
});
var GlobalStateContextProvider = ({
children
}) => {
const [globalLoading, setGlobalLoading] = useState({
isLoading: false
});
const [globalError, setGlobalError] = useState(null);
const [globalCtas, setGlobalCtas] = useState(null);
return /* @__PURE__ */ jsx2(
GlobalStateContext.Provider,
{
value: {
globalLoading,
setGlobalLoading,
globalError,
setGlobalError,
globalCtas,
setGlobalCtas
},
children
}
);
};
// lib/context/NotifiContextProviderWithWalletTargetPlugin.tsx
import { jsx as jsx3 } from "react/jsx-runtime";
var NotifiContextProviderWithWalletTargetPlugin = ({ children, ...params }) => {
const {
tenantId,
env,
storageOption,
isEnabledLoginViaTransaction,
...walletWithSignParams
} = params;
const contextValue = useXmpt({
walletWithSignParams
});
return /* @__PURE__ */ jsx3(NotifiFrontendClientContextProvider, { ...params, children: /* @__PURE__ */ jsx3(
NotifiTenantConfigContextProvider,
{
cardId: params.cardId,
inputs: params.inputs,
children: /* @__PURE__ */ jsx3(
NotifiTargetContextProvider,
{
toggleTargetAvailability: params.toggleTargetAvailability,
plugin: { walletTarget: contextValue },
children: /* @__PURE__ */ jsx3(NotifiTopicContextProvider, { children: /* @__PURE__ */ jsx3(
NotifiHistoryContextProvider,
{
notificationCountPerPage: params.notificationCountPerPage,
unreadCountScope: params.unreadCountScope,
children: /* @__PURE__ */ jsx3(NotifiUserSettingContextProvider, { children: /* @__PURE__ */ jsx3(GlobalStateContextProvider, { children }) })
}
) })
}
)
}
) });
};
export {
NotifiContextProviderWithWalletTargetPlugin,
NotifiWalletTargetContextProvider,
useWalletTargetContext
};
//# sourceMappingURL=index.mjs.map