UNPKG

@gumhq/react-sdk

Version:
1,382 lines (1,360 loc) 65.9 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { GATEWAY_SERVICE_URL: () => import_sdk6.GATEWAY_SERVICE_URL, GPLCORE_PROGRAMS: () => import_sdk6.GPLCORE_PROGRAMS, GPLSESSION_PROGRAMS: () => import_sdk6.GPLSESSION_PROGRAMS, GPL_NAMESERVICE_PROGRAMS: () => import_sdk6.GPL_NAMESERVICE_PROGRAMS, GRAPHQL_ENDPOINTS: () => import_sdk6.GRAPHQL_ENDPOINTS, GRAPHQL_ENDPOINTS_OLD: () => import_sdk6.GRAPHQL_ENDPOINTS_OLD, GUM_TLD_ACCOUNT: () => import_sdk6.GUM_TLD_ACCOUNT, GumNameService: () => import_sdk6.GumNameService, GumProvider: () => GumProvider, OLD_GPLCORE_PROGRAMS: () => import_sdk6.OLD_GPLCORE_PROGRAMS, SDK: () => import_sdk6.SDK, SessionWalletProvider: () => SessionWalletProvider, UploaderProvider: () => UploaderProvider, useArweaveStorage: () => useArweaveStorage, useBadge: () => useBadge, useCreatePost: () => useCreatePost, useCreateProfile: () => useCreateProfile, useDomains: () => useDomains, useExploreFeed: () => useExploreFeed, useFeed: () => useFeed, useFollow: () => useFollow, useGum: () => useGum, useGumContext: () => useGumContext, useNameService: () => useNameService, usePost: () => usePost, useProfile: () => useProfile, useReaction: () => useReaction, useSessionKeyManager: () => useSessionKeyManager, useSessionWallet: () => useSessionWallet, useShadowStorage: () => useShadowStorage, useUnfollow: () => useUnfollow, useUploader: () => useUploader, useUploaderContext: () => useUploaderContext }); module.exports = __toCommonJS(src_exports); // src/hooks/profile/useProfile.ts var import_react = require("react"); var useProfile = (sdk, profileAccount) => { const [profile, setProfile] = (0, import_react.useState)(null); const [profileLoading, setProfileLoading] = (0, import_react.useState)(false); const [profileError, setProfileError] = (0, import_react.useState)(null); const fetchProfile = (0, import_react.useCallback)( async () => { setProfileLoading(true); setProfileError(null); try { const data = await sdk.profile.getProfilesByProfileAccount(profileAccount); setProfile(data); } catch (err) { setProfileError(err); } finally { setProfileLoading(false); } }, [sdk, profileAccount] ); (0, import_react.useEffect)(() => { fetchProfile(); }, []); return { profile, profileLoading, profileError }; }; // src/hooks/profile/useCreateProfile.ts var import_react2 = require("react"); var useCreateProfile = (sdk) => { const [state, setState] = (0, import_react2.useState)({ isCreatingProfile: false, createProfileError: null }); const create = (0, import_react2.useCallback)( async (metadataUri, screenNameAccount, owner, payer = owner) => { setState({ isCreatingProfile: true, createProfileError: null }); try { const ixMethodBuilder = await createProfileIxMethodBuilder(metadataUri, screenNameAccount, owner, payer); await ixMethodBuilder?.instructionMethodBuilder.rpc(); setState({ isCreatingProfile: false, createProfileError: null }); return ixMethodBuilder?.profilePDA; } catch (err) { setState({ isCreatingProfile: false, createProfileError: err }); } }, [sdk] ); const getOrCreate = (0, import_react2.useCallback)( async (metadataUri, screenNameAccount, owner, payer = owner) => { setState({ isCreatingProfile: true, createProfileError: null }); try { const profilePDA = await sdk.profile.getOrCreate(metadataUri, screenNameAccount, owner, payer); setState({ isCreatingProfile: false, createProfileError: null }); return profilePDA; } catch (err) { setState({ isCreatingProfile: false, createProfileError: err }); } }, [sdk] ); const createProfileWithDomain = (0, import_react2.useCallback)( async (metadataUri, domainName, authority, payer = authority) => { setState({ isCreatingProfile: true, createProfileError: null }); try { const ixMethodBuilder = await sdk.profile.createProfileWithGumDomain(metadataUri, domainName, authority, payer); await ixMethodBuilder?.instructionMethodBuilder.rpc(); setState({ isCreatingProfile: false, createProfileError: null }); return ixMethodBuilder?.profilePDA; } catch (err) { setState({ isCreatingProfile: false, createProfileError: err }); } }, [sdk] ); const createProfileIxMethodBuilder = (0, import_react2.useCallback)( async (metadataUri, screenNameAccount, authority, payer) => { setState({ isCreatingProfile: true, createProfileError: null }); try { const createProfile = await sdk.profile.create(metadataUri, screenNameAccount, authority, payer); const data = { instructionMethodBuilder: createProfile.instructionMethodBuilder, profilePDA: createProfile.profilePDA }; setState({ isCreatingProfile: false, createProfileError: null }); return data; } catch (err) { setState({ isCreatingProfile: false, createProfileError: err }); return null; } }, [sdk] ); return { create, getOrCreate, createProfileWithDomain, createProfileIxMethodBuilder, ...state }; }; // src/hooks/badge/index.ts var import_sdk = require("@gumhq/sdk"); var import_react3 = require("react"); var import_web3 = require("@solana/web3.js"); var import_axios = __toESM(require("axios")); var useBadge = (sdk) => { const [state, setState] = (0, import_react3.useState)({ isProcessing: false, processingError: null }); const createBadge = (0, import_react3.useCallback)( async (metadataUri, issuer, schema, holder, updateAuthority, authority) => { setState({ isProcessing: true, processingError: null }); try { const { badgePDA, instructionMethodBuilder } = await sdk.badge.createBadge(metadataUri, issuer, schema, holder, updateAuthority, authority); await instructionMethodBuilder.rpc(); setState({ isProcessing: false, processingError: null }); return badgePDA; } catch (err) { setState({ isProcessing: false, processingError: err }); } }, [sdk.badge] ); const updateBadge = (0, import_react3.useCallback)( async (metadataUri, badgeAccount, issuer, schema, signer) => { setState({ isProcessing: true, processingError: null }); try { const instructionMethodBuilder = await sdk.badge.updateBadge(metadataUri, badgeAccount, issuer, schema, signer); await instructionMethodBuilder.rpc(); setState({ isProcessing: false, processingError: null }); } catch (err) { setState({ isProcessing: false, processingError: err }); } }, [sdk.badge] ); const createIssuer = (0, import_react3.useCallback)( async (authority) => { setState({ isProcessing: true, processingError: null }); try { const { issuerPDA, instructionMethodBuilder } = await sdk.badge.createIssuer(authority); await instructionMethodBuilder.rpc(); setState({ isProcessing: false, processingError: null }); return issuerPDA; } catch (err) { setState({ isProcessing: false, processingError: err }); } }, [sdk.badge] ); const createSchema = (0, import_react3.useCallback)( async (metadataUri, authority) => { setState({ isProcessing: true, processingError: null }); try { const { schemaPDA, instructionMethodBuilder } = await sdk.badge.createSchema(metadataUri, authority); await instructionMethodBuilder.rpc(); setState({ isProcessing: false, processingError: null }); return schemaPDA; } catch (err) { setState({ isProcessing: false, processingError: err }); } }, [sdk.badge] ); const issueGatewayBadge = (0, import_react3.useCallback)( async (wallet, holderWallet, holderProfile, schemaAccount, issuer, gumTld, appId, dateJoined, authority, updateAuthority) => { setState({ isProcessing: true, processingError: null }); const message = new TextEncoder().encode("Issue Gateway Badge"); if (!wallet.signMessage) { throw new Error("Wallet does not support signMessage"); } const signature = await wallet.signMessage(message); const [badgePDA, _] = import_web3.PublicKey.findProgramAddressSync( [ Buffer.from("badge"), issuer.toBuffer(), schemaAccount.toBuffer(), holderProfile.toBuffer() ], sdk.program.programId ); try { const gatewayResponse = await import_axios.default.post(`${import_sdk.GATEWAY_SERVICE_URL}/issueBadge`, { signature, userWallet: holderWallet.toBase58(), profileAddress: holderProfile.toBase58(), issuerAddress: issuer.toBase58(), badgeAddress: badgePDA.toBase58(), gumTld: gumTld.toBase58(), appName: appId, dateJoined, authority: authority.toBase58() }); const gatewayBadge = gatewayResponse.data.createCredential; if (!gatewayBadge) { throw new Error("Failed to issue gateway badge"); } const metadataUri = `gateway://${gatewayBadge.id}`; const badge = await createBadge( metadataUri, issuer, schemaAccount, holderProfile, updateAuthority || authority, authority ); setState({ isProcessing: false, processingError: null }); return badge; } catch (err) { setState({ isProcessing: false, processingError: err }); } }, [sdk.badge] ); return { createBadge, updateBadge, createIssuer, createSchema, issueGatewayBadge, ...state }; }; // src/hooks/nameservice/index.ts var import_react5 = require("react"); // src/hooks/nameservice/useDomains.ts var import_react4 = require("react"); var useDomains = (sdk, authority) => { const [userDomainAccounts, setUserDomainAccounts] = (0, import_react4.useState)([]); const [domainsLoading, setDomainsLoading] = (0, import_react4.useState)(false); const [domainsError, setDomainsError] = (0, import_react4.useState)(null); const fetchDomains = (0, import_react4.useCallback)( async () => { setDomainsLoading(true); setDomainsError(null); try { const accounts = await sdk.nameservice.getNameservicesByAuthority(authority.toBase58()); if (!accounts) return; const domainOptions = accounts.map((account) => { return { domainPDA: account.address, domainName: account.name }; }); setUserDomainAccounts(domainOptions); } catch (err) { setDomainsError(err); } finally { setDomainsLoading(false); } }, [authority, sdk] ); (0, import_react4.useEffect)(() => { fetchDomains(); }, [fetchDomains]); return { userDomainAccounts, domainsLoading, domainsError }; }; // src/hooks/nameservice/index.ts var useNameService = (sdk) => { const [state, setState] = (0, import_react5.useState)({ isCreating: false, creationError: null }); const getOrCreateDomain = (0, import_react5.useCallback)( async (tldPDA, domain, authority) => { setState({ isCreating: true, creationError: null }); try { const gumDomainPDA = await sdk.nameservice.getOrCreateDomain(tldPDA, domain, authority); setState({ isCreating: false, creationError: null }); return gumDomainPDA; } catch (err) { setState({ isCreating: false, creationError: err }); } }, [sdk] ); const transferDomain = (0, import_react5.useCallback)( async (domainPDA, currentAuthority, newAuthority) => { setState({ isCreating: true, creationError: null }); try { const instructionMethodBuilder = await sdk.nameservice.transferDomain(domainPDA, currentAuthority, newAuthority); await instructionMethodBuilder.rpc(); setState({ isCreating: false, creationError: null }); } catch (err) { setState({ isCreating: false, creationError: err }); } }, [sdk] ); return { getOrCreateDomain, transferDomain, ...state }; }; // src/hooks/post/usePost.ts var import_react6 = require("react"); var usePost = (sdk, postAccount) => { const [post, setPost] = (0, import_react6.useState)(null); const [postLoading, setPostLoading] = (0, import_react6.useState)(false); const [postError, setPostError] = (0, import_react6.useState)(null); const fetchPost = (0, import_react6.useCallback)( async () => { setPostLoading(true); setPostError(null); try { const data = await sdk.post.get(postAccount); setPost(data); } catch (err) { setPostError(err); } finally { setPostLoading(false); } }, [sdk, postAccount] ); (0, import_react6.useEffect)(() => { fetchPost(); }, []); return { post, postLoading, postError }; }; // src/hooks/post/useCreatePost.ts var import_react7 = require("react"); var useCreatePost = (sdk) => { const [postPDA, setPostPDA] = (0, import_react7.useState)(null); const [isCreatingPost, setIsCreatingPost] = (0, import_react7.useState)(false); const [createPostError, setCreatePostError] = (0, import_react7.useState)(null); const create = (0, import_react7.useCallback)( async (metadataUri, profileAccount, owner, payer = owner) => { setIsCreatingPost(true); setCreatePostError(null); try { const ixMethodBuilder = await createPostIxMethodBuilder(metadataUri, profileAccount, owner, payer); return await ixMethodBuilder?.rpc(); } catch (err) { setCreatePostError(err); } finally { setIsCreatingPost(false); } }, [sdk] ); const createWithSession = (0, import_react7.useCallback)( async (metadataUri, profileAccount, sessionPublicKey, sessionAccount, sendTransaction, payer = sessionPublicKey, connection, options) => { setIsCreatingPost(true); setCreatePostError(null); try { const ixMethodBuilder = await createPostWithSessionIxMethodBuilder(metadataUri, profileAccount, sessionPublicKey, sessionAccount, payer); const tx = await ixMethodBuilder?.transaction(); if (tx) { return await sendTransaction(tx, connection, options); } } catch (err) { setCreatePostError(err); } finally { setIsCreatingPost(false); } }, [sdk] ); const createPostIxMethodBuilder = (0, import_react7.useCallback)( async (metadataUri, profileAccount, owner, payer = owner) => { setCreatePostError(null); try { const data = await sdk.post.create(metadataUri, profileAccount, owner, payer); setPostPDA(data.postPDA); return data.instructionMethodBuilder; } catch (err) { setCreatePostError(err); return null; } }, [sdk] ); const createPostWithSessionIxMethodBuilder = (0, import_react7.useCallback)( async (metadataUri, profileAccount, sessionPublicKey, sessionAccount, payer = sessionPublicKey) => { setCreatePostError(null); try { const data = await sdk.post.createWithSession(metadataUri, profileAccount, sessionPublicKey, sessionAccount, payer); setPostPDA(data.postPDA); return data.instructionMethodBuilder; } catch (err) { setCreatePostError(err); return null; } }, [sdk] ); return { create, createWithSession, createPostIxMethodBuilder, createPostWithSessionIxMethodBuilder, postPDA, isCreatingPost, createPostError }; }; // src/hooks/post/useFeed.ts var import_react8 = require("react"); var useFeed = (sdk, profileAccount) => { const [feedData, setFeedData] = (0, import_react8.useState)(null); const [feedLoading, setFeedLoading] = (0, import_react8.useState)(false); const [feedError, setFeedError] = (0, import_react8.useState)(null); const fetchFeed = (0, import_react8.useCallback)( async () => { setFeedLoading(true); setFeedError(null); try { const data = await sdk.post.getFeedsByFollowedUsers(profileAccount); setFeedData(data); } catch (err) { setFeedError(err); } finally { setFeedLoading(false); } }, [sdk, profileAccount] ); (0, import_react8.useEffect)(() => { fetchFeed(); }, []); return { feedData, feedLoading, feedError }; }; // src/hooks/post/useExploreFeed.ts var import_react9 = require("react"); var useExploreFeed = (sdk) => { const [exploreFeedData, setExploreFeedData] = (0, import_react9.useState)(null); const [exploreFeedLoading, setExploreFeedLoading] = (0, import_react9.useState)(false); const [exploreFeedError, setExploreFeedError] = (0, import_react9.useState)(null); const fetchExploreFeed = (0, import_react9.useCallback)( async () => { setExploreFeedLoading(true); setExploreFeedError(null); try { const data = await sdk.post.getAllPosts(); setExploreFeedData(data); } catch (err) { setExploreFeedError(err); } finally { setExploreFeedLoading(false); } }, [sdk] ); (0, import_react9.useEffect)(() => { fetchExploreFeed(); }, []); return { exploreFeedData, exploreFeedLoading, exploreFeedError }; }; // src/hooks/reaction/useReaction.ts var import_react10 = require("react"); var useReaction = (sdk) => { const [reactionPDA, setReactionPDA] = (0, import_react10.useState)(null); const [isReacting, setIsReacting] = (0, import_react10.useState)(false); const [createReactionError, setCreateReactionError] = (0, import_react10.useState)(null); const createReaction = (0, import_react10.useCallback)( async (reaction, fromProfile, toPostAccount, owner, payer = owner) => { setIsReacting(true); setCreateReactionError(null); try { const ixMethodBuilder = await createReactionIxMethodBuilder(reaction, fromProfile, toPostAccount, owner, payer); if (ixMethodBuilder) { return await ixMethodBuilder.rpc(); } else { throw new Error("ixMethodBuilder is undefined"); } } catch (err) { setCreateReactionError(err); } finally { setIsReacting(false); } }, [sdk] ); const createReactionWithSession = (0, import_react10.useCallback)( async (reaction, fromProfile, toPostAccount, sessionPublicKey, sessionAccount, payer = sessionPublicKey, sendTransactionFn, connection, options) => { setIsReacting(true); setCreateReactionError(null); try { const ixMethodBuilder = await createReactionWithSessionIxMethodBuilder(reaction, fromProfile, toPostAccount, sessionPublicKey, sessionAccount, payer); if (ixMethodBuilder) { const tx = await ixMethodBuilder.transaction(); if (tx) { return await sendTransactionFn(tx, connection, options); } } else { throw new Error("ixMethodBuilder is undefined"); } } catch (err) { setCreateReactionError(err); } finally { setIsReacting(false); } }, [sdk] ); const createReactionIxMethodBuilder = (0, import_react10.useCallback)( async (reaction, fromProfile, toPostAccount, owner, payer = owner) => { try { const data = await sdk.reaction.create(fromProfile, toPostAccount, reaction, owner, payer); setReactionPDA(data.reactionPDA); return data.instructionMethodBuilder; } catch (err) { setCreateReactionError(err); return null; } }, [sdk] ); const createReactionWithSessionIxMethodBuilder = (0, import_react10.useCallback)( async (reaction, fromProfile, toPostAccount, sessionPublicKey, sessionTokenAccount, payer = sessionPublicKey) => { try { const data = await sdk.reaction.createWithSession(fromProfile, toPostAccount, reaction, sessionPublicKey, sessionTokenAccount, payer); setReactionPDA(data.reactionPDA); return data.instructionMethodBuilder; } catch (err) { setCreateReactionError(err); return null; } }, [sdk] ); const deleteReaction = (0, import_react10.useCallback)( async (reactionAccount, fromProfile, toPostAccount, owner, refundReceiver = owner) => { setIsReacting(true); try { const ixMethodBuilder = deleteReactionIxMethodBuilder(reactionAccount, fromProfile, toPostAccount, owner, refundReceiver); if (ixMethodBuilder) { return await ixMethodBuilder.rpc(); } else { throw new Error("ixMethodBuilder is undefined"); } } catch (err) { setCreateReactionError(err); } finally { setIsReacting(false); } }, [sdk] ); const deleteReactionWithSession = (0, import_react10.useCallback)( async (reactionAccount, fromProfile, toPostAccount, sessionPublicKey, sessionAccount, refundReceiver = sessionPublicKey, sendTransaction, connection, options) => { setIsReacting(true); try { const ixMethodBuilder = deleteReactionWithSessionIxMethodBuilder(reactionAccount, fromProfile, toPostAccount, sessionPublicKey, sessionAccount, refundReceiver); if (ixMethodBuilder) { const tx = await ixMethodBuilder.transaction(); if (tx) { return await sendTransaction(tx, connection, options); } } else { throw new Error("ixMethodBuilder is undefined"); } } catch (err) { setCreateReactionError(err); } finally { setIsReacting(false); } }, [sdk] ); const deleteReactionIxMethodBuilder = (0, import_react10.useCallback)((reactionAccount, fromProfile, toPostAccount, owner, refundReceiver = owner) => { setCreateReactionError(null); try { const data = sdk.reaction.delete(reactionAccount, toPostAccount, fromProfile, owner, refundReceiver); return data; } catch (err) { setCreateReactionError(err); return null; } }, [sdk]); const deleteReactionWithSessionIxMethodBuilder = (0, import_react10.useCallback)((reactionAccount, fromProfile, toPostAccount, sessionPublicKey, sessionAccount, refundReceiver = sessionPublicKey) => { setCreateReactionError(null); try { const data = sdk.reaction.deleteWithSession(reactionAccount, toPostAccount, fromProfile, sessionPublicKey, sessionAccount, refundReceiver); return data; } catch (err) { setCreateReactionError(err); return null; } }, [sdk]); return { createReaction, createReactionWithSession, createReactionIxMethodBuilder, createReactionWithSessionIxMethodBuilder, deleteReaction, deleteReactionWithSession, deleteReactionIxMethodBuilder, deleteReactionWithSessionIxMethodBuilder, reactionPDA, isReacting, createReactionError }; }; // src/hooks/connection/useFollow.ts var import_react11 = require("react"); var useFollow = (sdk) => { const [connectionPDA, setConnectionPDA] = (0, import_react11.useState)(null); const [connectionLoading, setConnectionLoading] = (0, import_react11.useState)(false); const [connectionError, setConnectionError] = (0, import_react11.useState)(null); const follow = (0, import_react11.useCallback)( async (fromProfile, toProfile, owner, payer = owner) => { setConnectionLoading(true); setConnectionError(null); try { const ixMethodBuilder = await createConnectionIxMethodBuilder( fromProfile, toProfile, owner, payer ); if (ixMethodBuilder) { return await ixMethodBuilder.rpc(); } else { const error = new Error("ixMethodBuilder is undefined"); setConnectionError(error); return Promise.reject(error); } } catch (err) { setConnectionError(err); } finally { setConnectionLoading(false); } }, [sdk] ); const followWithSession = (0, import_react11.useCallback)( async (fromProfile, toProfile, sessionPublicKey, sessionAccount, sendTransaction, payer = sessionPublicKey, connection, options) => { setConnectionLoading(true); setConnectionError(null); try { const ixMethodBuilder = await createConnectionWithSessionIxMethodBuilder( fromProfile, toProfile, sessionPublicKey, sessionAccount, payer ); if (ixMethodBuilder) { const tx = await ixMethodBuilder.transaction(); if (tx) { return await sendTransaction(tx, connection, options); } } else { const error = new Error("ixMethodBuilder is undefined"); setConnectionError(error); return Promise.reject(error); } } catch (err) { setConnectionError(err); } finally { setConnectionLoading(false); } }, [sdk] ); const createConnectionIxMethodBuilder = (0, import_react11.useCallback)( async (fromProfile, toProfile, owner, payer = owner) => { try { const connection = await sdk.connection.create( fromProfile, toProfile, owner, payer ); setConnectionPDA(connection.connectionPDA); return connection.instructionMethodBuilder; } catch (err) { setConnectionError(err); return null; } }, [sdk] ); const createConnectionWithSessionIxMethodBuilder = (0, import_react11.useCallback)( async (fromProfile, toProfile, sessionPublicKey, sessionAccount, payer = sessionPublicKey) => { try { const connection = await sdk.connection.createWithSession( fromProfile, toProfile, sessionPublicKey, sessionAccount, payer ); setConnectionPDA(connection.connectionPDA); return connection.instructionMethodBuilder; } catch (err) { setConnectionError(err); return null; } }, [sdk] ); return { follow, followWithSession, createConnectionIxMethodBuilder, createConnectionWithSessionIxMethodBuilder, connectionPDA, connectionLoading, connectionError }; }; // src/hooks/connection/useUnfollow.ts var import_react12 = require("react"); var useUnfollow = (sdk) => { const [connectionLoading, setConnectionLoading] = (0, import_react12.useState)(false); const [connectionError, setConnectionError] = (0, import_react12.useState)(null); const unfollow = (0, import_react12.useCallback)( async (connectionAccount, fromProfile, toProfile, owner, refundReceiver = owner) => { setConnectionLoading(true); setConnectionError(null); try { const ixMethodBuilder = await deleteConnectionIxMethodBuilder( connectionAccount, fromProfile, toProfile, owner, refundReceiver ); if (ixMethodBuilder) { return await ixMethodBuilder.rpc(); } else { const error = new Error("ixMethodBuilder is undefined"); setConnectionError(error); return Promise.reject(error); } } catch (err) { setConnectionError(err); } finally { setConnectionLoading(false); } }, [sdk] ); const unfollowWithSession = (0, import_react12.useCallback)( async (connectionAccount, fromProfile, toProfile, sessionPublicKey, sessionAccount, sendTransaction, refundReceiver = sessionPublicKey, connection, options) => { setConnectionLoading(true); setConnectionError(null); try { const ixMethodBuilder = await deleteConnectionWithSessionIxMethodBuilder( connectionAccount, fromProfile, toProfile, sessionPublicKey, sessionAccount, refundReceiver ); if (ixMethodBuilder) { const tx = await ixMethodBuilder.transaction(); if (tx) { return await sendTransaction(tx, connection, options); } } else { const error = new Error("ixMethodBuilder is undefined"); setConnectionError(error); return Promise.reject(error); } } catch (err) { setConnectionError(err); } finally { setConnectionLoading(false); } }, [sdk] ); const deleteConnectionIxMethodBuilder = (0, import_react12.useCallback)( async (connectionAccount, fromProfile, toProfile, owner, refundReceiver = owner) => { try { const connection = sdk.connection.delete( connectionAccount, fromProfile, toProfile, owner, refundReceiver ); return connection; } catch (err) { setConnectionError(err); return null; } }, [sdk] ); const deleteConnectionWithSessionIxMethodBuilder = (0, import_react12.useCallback)( async (connectionAccount, fromProfile, toProfile, sessionPublicKey, sessionAccount, refundReceiver = sessionPublicKey) => { try { const connection = sdk.connection.deleteWithSession( connectionAccount, fromProfile, toProfile, sessionPublicKey, sessionAccount, refundReceiver ); return connection; } catch (err) { setConnectionError(err); return null; } }, [sdk] ); return { unfollow, unfollowWithSession, deleteConnectionIxMethodBuilder, deleteConnectionWithSessionIxMethodBuilder, connectionLoading, connectionError }; }; // src/hooks/session/useSessionKeyManager.ts var import_web32 = require("@solana/web3.js"); var import_react13 = require("react"); // src/utils/crypto.ts var CryptoJS = __toESM(require("crypto-js")); var ENCRYPTION_KEY_LENGTH = 32; function generateEncryptionKey() { const key = CryptoJS.lib.WordArray.random(ENCRYPTION_KEY_LENGTH); return CryptoJS.enc.Base64.stringify(key); } function encrypt(data, password) { const iv = CryptoJS.lib.WordArray.random(16); const passwordHash = CryptoJS.SHA256(password); const cipher = CryptoJS.AES.encrypt(data, passwordHash, { iv }); const encryptedData = cipher.ciphertext.toString(CryptoJS.enc.Base64); return `${encryptedData}.${iv.toString(CryptoJS.enc.Base64)}`; } function decrypt(data, password) { const [encryptedDataString, ivString] = data.split("."); const encryptedData = CryptoJS.enc.Base64.parse(encryptedDataString); const iv = CryptoJS.enc.Base64.parse(ivString); const passwordHash = CryptoJS.SHA256(password); const cipherParams = CryptoJS.lib.CipherParams.create({ ciphertext: encryptedData }); const decryptedData = CryptoJS.AES.decrypt(cipherParams, passwordHash, { iv }); return decryptedData.toString(CryptoJS.enc.Utf8); } // src/hooks/session/useSessionKeyManager.ts var import_sdk2 = require("@gumhq/sdk"); var nacl = __toESM(require("tweetnacl")); var import_anchor = require("@project-serum/anchor"); // src/utils/indexedDB.ts var DB_NAME = "session_data"; var SESSION_OBJECT_STORE = "sessions"; var WALLET_PUBKEY_TO_SESSION_STORE = "walletPublicKeyToSessionData"; var ENCRYPTION_KEY_OBJECT_STORE = "user_preferences"; var openIndexedDB = async () => { return new Promise((resolve, reject) => { const request = indexedDB.open(DB_NAME, 1); request.onupgradeneeded = (event) => { const db = request.result; db.createObjectStore(SESSION_OBJECT_STORE); db.createObjectStore(ENCRYPTION_KEY_OBJECT_STORE); db.createObjectStore(WALLET_PUBKEY_TO_SESSION_STORE); }; request.onsuccess = (event) => { resolve(request.result); }; request.onerror = (event) => { reject(request.error); }; }); }; var getItemFromIndexedDB = async (storeName, key) => { const db = await openIndexedDB(); return new Promise((resolve, reject) => { const transaction = db.transaction(storeName, "readonly"); const store = transaction.objectStore(storeName); const request = store.get(key); request.onsuccess = (event) => { resolve(request.result); }; request.onerror = (event) => { reject(request.error); }; }); }; var setItemToIndexedDB = async (storeName, data, key) => { const db = await openIndexedDB(); return new Promise((resolve, reject) => { const transaction = db.transaction(storeName, "readwrite"); const store = transaction.objectStore(storeName); const request = store.put(data, key); request.onsuccess = (event) => { resolve(); }; request.onerror = (event) => { reject(request.error); }; }); }; var deleteItemFromIndexedDB = async (storeName, key) => { const db = await openIndexedDB(); return new Promise((resolve, reject) => { const transaction = db.transaction(storeName, "readwrite"); const store = transaction.objectStore(storeName); const request = store.delete(key); request.onsuccess = (event) => { resolve(); }; request.onerror = (event) => { reject(request.error); }; }); }; // src/hooks/session/useSessionKeyManager.ts var SESSION_OBJECT_STORE2 = "sessions"; var WALLET_PUBKEY_TO_SESSION_STORE2 = "walletPublicKeyToSessionData"; var ENCRYPTION_KEY_OBJECT_STORE2 = "user_preferences"; function useSessionKeyManager(wallet, connection, cluster) { const keypairRef = (0, import_react13.useRef)(null); const sessionTokenRef = (0, import_react13.useRef)(null); const [, forceUpdate] = (0, import_react13.useState)({}); const [isLoading, setIsLoading] = (0, import_react13.useState)(false); const [error, setError] = (0, import_react13.useState)(null); const sessionConnection = connection; const sdk = new import_sdk2.SessionTokenManager(wallet, connection, cluster); const generateKeypair = () => { keypairRef.current = import_web32.Keypair.generate(); }; const loadKeypairFromDecryptedSecret = (decryptedKeypair) => { keypairRef.current = import_web32.Keypair.fromSecretKey(new Uint8Array(Buffer.from(decryptedKeypair, "base64"))); }; const triggerRerender = () => { forceUpdate({}); }; (0, import_react13.useEffect)(() => { if (!wallet) { return; } getSessionToken().then((token) => { if (!token) { resetSessionData(); } }).catch(() => { resetSessionData(); }); }, [wallet, wallet?.publicKey, cluster]); const deleteSessionData = async () => { try { const walletPublicKey = wallet.publicKey.toBase58(); const sessionKey = await getItemFromIndexedDB(WALLET_PUBKEY_TO_SESSION_STORE2, walletPublicKey); if (sessionKey) { await deleteItemFromIndexedDB(SESSION_OBJECT_STORE2, sessionKey); await deleteItemFromIndexedDB(WALLET_PUBKEY_TO_SESSION_STORE2, walletPublicKey); } await deleteItemFromIndexedDB(ENCRYPTION_KEY_OBJECT_STORE2, walletPublicKey); } catch (error2) { console.error("Error deleting session data:", error2); setError(error2); } }; const withLoading = async (asyncFunction) => { setError(null); setIsLoading(true); try { const result = await asyncFunction(); return result; } finally { setIsLoading(false); } }; const signTransaction = async (transaction) => { return withLoading(async () => { if (!keypairRef.current || !sessionTokenRef.current) { throw new Error("Cannot sign transaction - keypair or session token not loaded. Please create a session first."); } const { blockhash } = await connection.getLatestBlockhash("finalized"); const feePayer = keypairRef.current.publicKey; transaction.recentBlockhash = transaction.recentBlockhash || blockhash; transaction.feePayer = transaction.feePayer || feePayer; transaction.sign(keypairRef.current); return transaction; }); }; const signAllTransactions = async (transactions) => { return withLoading(async () => { return Promise.all(transactions.map((transaction) => signTransaction(transaction))); }); }; const signMessage = async (message) => { return withLoading(async () => { if (!keypairRef.current) { throw new Error("Cannot sign message - keypair not loaded. Please create a session first."); } return nacl.sign.detached(message, keypairRef.current.secretKey); }); }; const sendTransaction = async (transaction, connection2, options = {}) => { return withLoading(async () => { const keypair = keypairRef.current; const sessionToken = sessionTokenRef.current; if (!connection2) { connection2 = sessionConnection; } if (!keypair || !sessionToken) { throw new Error( "Cannot sign transaction - keypair or session token not loaded. Please create a session first." ); } const { signers, ...sendOptions } = options; const publicKey = keypair.publicKey; if (!publicKey) { throw new Error( "Cannot send transaction - keypair not loaded. Please create a session first." ); } transaction.feePayer = transaction.feePayer || publicKey; transaction.recentBlockhash = transaction.recentBlockhash || (await connection2.getLatestBlockhash({ commitment: sendOptions.preflightCommitment, minContextSlot: sendOptions.minContextSlot })).blockhash; if (signers?.length) { transaction.partialSign(...signers); } transaction = await signTransaction(transaction); const txid = await connection2.sendRawTransaction( transaction.serialize(), sendOptions ); return txid; }); }; const signAndSendTransaction = async (transaction, connection2, options = {}) => { return withLoading(async () => { if (!connection2) { connection2 = sessionConnection; } const transactionsArray = Array.isArray(transaction) ? transaction : [transaction]; const txids = await Promise.all(transactionsArray.map((signedTransaction) => sendTransaction(signedTransaction, connection2, options))); return txids; }); }; const getSessionToken = async () => { try { const sessionKey = await getItemFromIndexedDB(WALLET_PUBKEY_TO_SESSION_STORE2, wallet.publicKey.toString()); if (!sessionKey) { resetSessionData(); return null; } const encryptedSessionData = await getItemFromIndexedDB(SESSION_OBJECT_STORE2, sessionKey); const encryptionKey = await getItemFromIndexedDB(ENCRYPTION_KEY_OBJECT_STORE2, wallet.publicKey.toString()); if (!encryptedSessionData || !encryptionKey) { resetSessionData(); return null; } if (encryptedSessionData && encryptionKey) { const { encryptedToken, encryptedKeypair, validUntilTimestamp } = encryptedSessionData; const { userPreferences: storedEncryptionKey, validUntilTimestamp: encryptionKeyExpiry } = encryptionKey; const currentTimestamp = Math.ceil(Date.now() / 1e3); if (currentTimestamp > encryptionKeyExpiry || currentTimestamp > validUntilTimestamp) { await deleteSessionData(); return null; } const decryptedToken = decrypt(encryptedToken, storedEncryptionKey); const decryptedKeypair = decrypt(encryptedKeypair, storedEncryptionKey); loadKeypairFromDecryptedSecret(decryptedKeypair); sessionTokenRef.current = decryptedToken; triggerRerender(); return decryptedToken; } } catch (error2) { console.error("Error getting session data from IndexedDB:", error2); setError(error2); } return null; }; const createSession = async (targetProgramPublicKey, topUp = false, expiryInMinutes = 60, sessionCreatedCallback) => { return withLoading(async () => { try { if (expiryInMinutes > 24 * 60) { throw new Error("Expiry cannot be more than 24 hours."); } if (!keypairRef.current) { generateKeypair(); } const expiryTimestamp = Math.ceil((Date.now() + expiryInMinutes * 60 * 1e3) / 1e3); const validUntilBN = new import_anchor.BN(expiryTimestamp); const sessionKeypair = keypairRef.current; if (!sessionKeypair) { throw new Error("Session keypair not generated."); } const sessionSignerPublicKey = sessionKeypair.publicKey; const instructionMethodBuilder = sdk.program.methods.createSession(topUp, validUntilBN).accounts({ targetProgram: targetProgramPublicKey, sessionSigner: sessionSignerPublicKey, authority: wallet.publicKey }); const pubKeys = await instructionMethodBuilder.pubkeys(); const sessionToken = pubKeys.sessionToken; await instructionMethodBuilder.signers([sessionKeypair]).rpc(); await deleteSessionData(); const encryptionKey = generateEncryptionKey(); const sessionTokenString = sessionToken.toBase58(); const keypairSecretBase64String = Buffer.from(sessionKeypair.secretKey).toString("base64"); const encryptedToken = encrypt(sessionTokenString, encryptionKey); const encryptedKeypair = encrypt(keypairSecretBase64String, encryptionKey); const encryptedSessionData = { encryptedToken, encryptedKeypair, validUntilTimestamp: expiryTimestamp }; await setItemToIndexedDB(SESSION_OBJECT_STORE2, encryptedSessionData, sessionTokenString); await setItemToIndexedDB(WALLET_PUBKEY_TO_SESSION_STORE2, sessionTokenString, wallet.publicKey.toBase58()); await setItemToIndexedDB(ENCRYPTION_KEY_OBJECT_STORE2, { "userPreferences": encryptionKey, validUntilTimestamp: expiryTimestamp }, wallet.publicKey.toBase58()); sessionTokenRef.current = sessionTokenString; triggerRerender(); if (!sessionTokenRef.current) { console.error("Session token not generated."); } if (sessionCreatedCallback) { sessionCreatedCallback({ sessionToken: sessionTokenRef.current, publicKey: sessionSignerPublicKey.toBase58() }); } return { ownerPublicKey: wallet.publicKey, isLoading: false, error: null, sessionToken: sessionTokenRef.current, publicKey: sessionSignerPublicKey, signMessage, signTransaction, signAllTransactions, signAndSendTransaction, sendTransaction }; } catch (error2) { console.error("Error creating session:", error2); setError(error2); return { publicKey: wallet.publicKey, ownerPublicKey: null, isLoading: false, error: error2.message, sessionToken: null, signTransaction: null, signAllTransactions: null, signMessage: null, sendTransaction: null, signAndSendTransaction: null, getSessionToken: null, createSession: null, revokeSession: null }; } }); }; const resetSessionData = () => { keypairRef.current = null; sessionTokenRef.current = null; triggerRerender(); }; const revokeSession = async () => { return withLoading(async () => { try { if (!sessionTokenRef.current || !keypairRef.current) { return; } const sessionTokenPublicKey = keypairRef.current.publicKey; const instructionMethodBuilder = sdk.program.methods.revokeSession().accounts({ sessionToken: sessionTokenRef.current, authority: wallet.publicKey }); const txId = await instructionMethodBuilder.rpc(); const sessionSignerSolanaBalance = await connection.getBalance(sessionTokenPublicKey); if (sessionSignerSolanaBalance > 0) { const tx = new import_web32.Transaction().add( import_web32.SystemProgram.transfer({ fromPubkey: sessionTokenPublicKey, toPubkey: wallet.publicKey, lamports: sessionSignerSolanaBalance }) ); tx.feePayer = sessionTokenPublicKey; tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; const estimatedFee = await tx.getEstimatedFee(connection); if (estimatedFee && sessionSignerSolanaBalance > estimatedFee) { const transaction = new import_web32.Transaction().add( import_web32.SystemProgram.transfer({ fromPubkey: sessionTokenPublicKey, toPubkey: wallet.publicKey, lamports: sessionSignerSolanaBalance - estimatedFee }) ); await sendTransaction(transaction); } } const walletPublicKey = wallet.publicKey.toBase58(); await deleteItemFromIndexedDB(SESSION_OBJECT_STORE2, sessionTokenRef.current); await deleteItemFromIndexedDB(ENCRYPTION_KEY_OBJECT_STORE2, walletPublicKey); await deleteItemFromIndexedDB(WALLET_PUBKEY_TO_SESSION_STORE2, walletPublicKey); resetSessionData(); return txId; } catch (error2) { console.error("Error revoking session:", error2); setError(error2); return null; } }); }; if (!wallet) { return { publicKey: null, ownerPublicKey: null, isLoading: false, sessionToken: null, signTransaction: void 0, signAllTransactions: void 0, signMessage: void 0, sendTransaction: void 0, signAndSendTransaction: void 0, getSessionToken: async () => null, createSession: async () => void 0, revokeSession: async () => null, error }; } return { publicKey: sessionTokenRef.current && keypairRef.current ? keypairRef.current.publicKey : null, ownerPublicKey: wallet.publicKey, isLoading, error, sessionToken: sessionTokenRef.current, signTransaction, signAllTransactions, signMessage, sendTransaction, signAndSendTransaction, getSessionToken, createSession, revokeSession }; } // src/hooks/storage/useUploader.ts var import_react16 = require("react"); // src/hooks/storage/arweave/useArweave.ts var import_react14 = require("react"); var import_client = require("@bundlr-network/client"); var import_web33 = require("@solana/web3.js"); function isSessionWallet(wallet) { return "sessionToken" in wallet; } var useArweaveStorage = (connection, cluster) => { const BUNDLR_URL = cluster === "devnet" ? "https://devnet.bundlr.network" : "https://node2.bundlr.network"; const initializeBundlr = async (wallet) => { if (isSessionWallet(wallet) && !wallet.sessionToken) { throw new Error("Session is required for arweave uploader"); } const newBundlr = new import_client.WebBundlr(BUNDLR_URL, "solana", wallet, { providerUrl: connection.rpcEndpoint }); await newBundlr.ready(); return newBundlr; }; const withErrorHandling = (0, import_react14.useCallback)( (fn) => async (...args) => { try { const result = await fn(...args); return { ...result, error: null }; } catch (e) { return { url: null, error: e.message }; } }, [] ); const uploadData = (0, import_react14.useCallback)( withErrorHandling(async (data, wallet) => { const bundlr = await initializeBundlr(wallet); if (!bundlr) { throw new Error("Bundlr not initialized"); } const publicKey = wallet?.publicKey; if (!publicKey) { throw new Error("Public key not found"); } if (typeof data === "object") { data = JSON.stringify(data); } const transaction = bundlr.createTransaction(data); try { await transaction.sign(); await transaction.upload(); } catch (e) { if (e.message.includes("Not enough funds to send data")) { const price = await bundlr.getPrice(data.length); const minimumFunds = price.multipliedBy(1); const balance = await bundlr.getBalance(publicKey.toBase58()); if (balance.isLessThan(minimumFunds)) { await bundlr.fund(minimumFunds);