Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

frame SDK Implementation and Usage #22

Open
vikashyap opened this issue Mar 26, 2024 · 1 comment
Open

frame SDK Implementation and Usage #22

vikashyap opened this issue Mar 26, 2024 · 1 comment
Assignees

Comments

@vikashyap
Copy link
Contributor

vikashyap commented Mar 26, 2024

Iframe SDK Implementation and Usage

  1. Changing tabs into URL routes, using react react-router
    sdk can be serve by /unstake, /swap , /stake

  2. To streamline our application architecture and enhance reusability, we've encapsulated the functionality of embedding our SDK within iframes into a separate package. This package allows us to generate iframe URLs tailored to specific configurations, making it easy to integrate our SDK into various projects.

Iframe SDK Package Structure:

In the App component of our Iframe application, we utilize the useIframe hook from our package to generate a query string based on the provided configuration. This query string is then used to construct the URL for the iframe, allowing us to embed our SDK seamlessly into any web page.

Example Implementation of useIframe Hook:

The useIframe hook takes a configuration object containing token addresses and tab settings as input and returns a query string suitable for constructing iframe URLs. This hook ensures that only valid data is used to generate the query string, enhancing security and reliability.

Use of hook into Iframe application

import { useIframe } from "../../sdk/lib/hooks/iframe"; //Todo: make this hook a package and import it from there
import "./App.css";

function App() {
  const { queryString } = useIframe({
    matic: "0x43ef285f5e27d8ca978a7e577f4ddf52147eb77b",
    livepeer: "0x4a3c14d7450c30f712e89659af21f90df56bc9ba",
    graph: "0x4003e23be46f3bf2b50c3c7f8b13aaecdc71ea72",
    isStaked: true,
    isUnstaked: true,
    isSwapped: false,
  });
 `returned  queryString ?matic=0x43ef285f5e27d8ca978a7e577f4ddf52147eb77b&livepeer=0x4a3c14d7450c30f712e89659af21f90df56bc9ba&graph=0x4003e23be46f3bf2b50c3c7f8b13aaecdc71ea72&isStaked=true&isUnstaked=true&isSwapped=true&isStaked=true&isUnstaked=true&isSwapped=false`
  
  return (
    <iframe
      src={`http://localhost:5174/stake/?${queryString}`}
      height="660px"
      width="100%"
      style={{
        border: 0,
        margin: "0 auto",
        marginBottom: ".5rem",
        display: "block",
        borderRadius: "10px",
        maxWidth: "960px",
        minWidth: "400px",
      }}
    />
  );
}

export default App;

Implementation example of useIframe

type IframeTokenConfigMap = {
  [Key in TokenSlugEnums]?: Address;
};

type IframeTabsConfigMap = {
  isStaked?: boolean;
  isUnstaked?: boolean;
  isSwapped?: boolean;
};

type IframeConfigMap = IframeTokenConfigMap & IframeTabsConfigMap;

export const useIframe = (
  configMap: IframeConfigMap
): { queryString: string } => {
  const [queryString, setQueryString] = useState("");

  useEffect(() => {
    let query = "?";
    Object.entries(configMap).forEach(([key, value]) => {
    
    // write a logic to make sure tenderizer address is valid address
    and then add into config 
    
      if (key && value) {
        query += `${key}=${value}&`;
      }
    });
    // Add boolean properties to query string
    query += `isStaked=${configMap.isStaked ?? true}&`;
    query += `isUnstaked=${configMap.isUnstaked ?? true}&`;
    query += `isSwapped=${configMap.isSwapped ?? true}`;

    setQueryString(query);
  }, [configMap]);

  return { queryString };
};

function convertStringIntoObject(queryString:string):IframeConfigMap{
// logic of converting string here
return{
    matic: "0x43ef285f5e27d8ca978a7e577f4ddf52147eb77b",
    livepeer: "0x4a3c14d7450c30f712e89659af21f90df56bc9ba",
    graph: "0x4003e23be46f3bf2b50c3c7f8b13aaecdc71ea72",
    isStaked: true,
    isUnstaked: true,
    isSwapped: false,
  }
}

Integration in SDK Main Application:

In the main entry point of our SDK application, we parse the query parameters from the URL and use the convertStringIntoObject function to transform them into a structured configuration object. We then utilize the useIframeStoreData hook to store this data, enabling dynamic configuration of our SDK based on the parameters passed via the URL.

// read the params from URL in sdk
const parmsOBJ = convertStringIntoObject(window.location.search);

const IframeConfig = useIframeConfig(parmasOBJ) // returns valid config according to parmsOBJ

const activeConfig = {
config,
...(Object.keys(IframeConfig).length > 0 && {IframeConfig})
}

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <ThemeProvider>
      <TenderizeProvider config={activeConfig}>
        <Web3Provider config={config.web3}>
          <App />
        </Web3Provider>
      </TenderizeProvider>
    </ThemeProvider>
  </React.StrictMode>
);
@kyriediculous
Copy link
Member

kyriediculous commented Mar 26, 2024

I like the way you are thinking about how the iframes will be used.

However one comment here, do you think it is worth exposing the functionality to create the URL not as a hook but as a vanilla JS/TS function ?

Otherwise this could only be used from react applications if I am not mistaken.


Another comment is regarding the config. I think we can make the iframe config match our sdk config , or at least partially since the iframes config provider will already have some of it preconfigured.

I'm trying to think about reusability of the Config data model here across the SDK.

In other words, I'd like us o think about config holistically rather than in isolation for only the iframe.

One good starting point is taking the current config options and listing what other requirement we have then come up with a data model (type) for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants