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

feat: add replacement map feature #176

Merged
merged 8 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 5 additions & 22 deletions frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ First, download the bos-loader cli by following this guide [here](https://docs.n
From the root of QueryAPI Frontend repo, run the following command

```bash
yarn serve:widgets
yarn serve:widgets:local // for running local enviornment
yarn serve:widgets:dev // for running dev enviornment
yarn serve:widgets:prod // for running prod enviornment
```
> Near.org or any other BOS gateway queries the blockchain state to pull the latest widgets code and renders it. If we would like to test our BOS widgets, we need to override the path at which the gateway (near.org) queries for the widget code. We do this using the Bos-loader tool (the underlying CLI tool used in the `yarn serve:widgets` command) which allows us to serve out widgets locally (http://127.0.0.1:3030 by default). At this point, we have served our widgets locally but have not yet told the BOS gateway (near.org) where to load our local widgets from.
> Near.org or any other BOS gateway queries the blockchain state to pull the latest widgets code and renders it. If we would like to test our BOS widgets, we need to override the path at which the gateway (near.org) queries for the widget code. We do this using the Bos-loader tool (the underlying CLI tool used in the `yarn serve:widgets:dev` command) which allows us to serve out widgets locally (http://127.0.0.1:3030 by default). ** This command replaces all keys found in `replacement.dev.json` object with the their values in the widgets directory when serving the widgets **. At this point, we have served our widgets locally but have not yet told the BOS gateway (near.org) where to load our local widgets from.


**Then, Head to `near.org/flags` and enter `http://127.0.0.1:3030`**
Expand All @@ -26,26 +28,7 @@ yarn serve:widgets
yarn dev
```


**Now, head to the path where the widgets are served on the BOS.**

- Prod Environment: `https://near.org/dataplatform.near/widget/QueryApi.App`
- Dev Environment: `https://near.org/dev-queryapi.dataplatform.near/widget/QueryApi.dev-App`

---
### Notes
> **Make sure to change your widgets code (while testing only) to point to where your local nextJS app is being served.**

```QueryApi.App.jsx
---const EXTERNAL_APP_URL = "https://queryapi.io";
+++const EXTERNAL_APP_URL = "http://localhost:3000";
```


> **You may need to change the accountId argument to the bos-loader CLI command in `package.json` to load from `dataplatform.near` or `dev-queryapi.dataplatform.near`. This depends on what environment you are testing for.**

`bos-loader dev-queryapi.dataplatform.near --path widgets/src`
`bos-loader dataplatform.near --path widgets/src`


- Prod App: `https://near.org/dataplatform.near/widget/QueryApi.App`

4 changes: 3 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"private": true,
"scripts": {
"dev": "next dev",
"serve:widgets": "bos-loader dev-queryapi.dataplatform.near --path widgets/src",
"serve:widgets": "bos-loader dataplatform.near --path widgets/src -r replacement.mainnet.json",
"serve:widgets:local": "bos-loader dataplatform.near --path widgets/src -r replacement.local.json",
"serve:widgets:dev": "bos-loader dev-queryapi.dataplatform.near --path widgets/src -r replacement.dev.json",
"build": "next build",
"start": "next start",
"lint": "next lint"
Expand Down
6 changes: 6 additions & 0 deletions frontend/replacement.dev.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"REPL_ACCOUNT_ID": "dev-queryapi.dataplatform.near",
"REPL_GRAPHQL_ENDPOINT": "https://near-queryapi.dev.api.pagoda.co",
"REPL_EXTERNAL_APP_URL": "https://queryapi-frontend-vcqilefdcq-ew.a.run.app",
"REPL_REGISTRY_CONTRACT_ID,": "dev-queryapi.dataplatform.near"
}
6 changes: 6 additions & 0 deletions frontend/replacement.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"REPL_ACCOUNT_ID": "dataplatform.near",
"REPL_GRAPHQL_ENDPOINT": "https://near-queryapi.api.pagoda.co",
"REPL_EXTERNAL_APP_URL": "http://localhost:3000",
"REPL_REGISTRY_CONTRACT_ID,": "queryapi.dataplatform.near"
}
6 changes: 6 additions & 0 deletions frontend/replacement.mainnet.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"REPL_ACCOUNT_ID": "dataplatform.near",
"REPL_GRAPHQL_ENDPOINT": "https://near-queryapi.api.pagoda.co",
"REPL_EXTERNAL_APP_URL": "https://queryapi-frontend-24ktefolwq-ew.a.run.app",
"REPL_REGISTRY_CONTRACT_ID,": "queryapi.dataplatform.near"
}
11 changes: 1 addition & 10 deletions frontend/widgets/src/QueryApi.App.jsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
const GRAPHQL_ENDPOINT =
"https://queryapi-hasura-graphql-24ktefolwq-ew.a.run.app";
const APP_OWNER = "dataplatform.near";
const EXTERNAL_APP_URL = "https://queryapi-frontend-24ktefolwq-ew.a.run.app";
const REGISTRY_CONTRACT_ID = "queryapi.dataplatform.near";
const view = props.view;
const path = props.path;
const tab = props.tab;
const selectedIndexerPath = props.selectedIndexerPath;

return (
<Widget
src={`${APP_OWNER}/widget/QueryApi.Dashboard`}
src={`${REPL_ACCOUNT_ID}/widget/QueryApi.Dashboard`}
props={{
GRAPHQL_ENDPOINT,
APP_OWNER,
EXTERNAL_APP_URL,
REGISTRY_CONTRACT_ID,
view,
path,
tab,
Expand Down
55 changes: 11 additions & 44 deletions frontend/widgets/src/QueryApi.Dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,6 @@ const [selected_accountId, selected_indexerName] = props.selectedIndexerPath
const activeTab = props.view ?? "indexers";
const limit = 7;
let totalIndexers = 0;
const REGISTRY_CONTRACT_ID =
props.REGISTRY_CONTRACT_ID || "queryapi.dataplatform.near";
const APP_OWNER = props.APP_OWNER || "dataplatform.near";
const GRAPHQL_ENDPOINT =
props.GRAPHQL_ENDPOINT ||
"https://queryapi-hasura-graphql-24ktefolwq-ew.a.run.app";
const EXTERNAL_APP_URL =
props.EXTERNAL_APP_URL || "https://queryapi-frontend-24ktefolwq-ew.a.run.app";

let appPath = props.isDev ? "dev-App" : "App";

State.init({
activeTab: Storage.privateGet("queryapi:activeTab") || activeTab,
Expand All @@ -25,7 +15,7 @@ State.init({
selected_account: undefined,
});

Near.asyncView(REGISTRY_CONTRACT_ID, "list_indexer_functions").then((data) => {
Near.asyncView(`${REGISTRY_CONTRACT_ID}`, "list_indexer_functions").then((data) => {
const indexers = [];
const total_indexers = 0;
Object.keys(data.All).forEach((accountId) => {
Expand Down Expand Up @@ -299,10 +289,9 @@ const selectTab = (tabName) => {
};

const indexerView = (accountId, indexerName) => {
const editUrl = `https://near.org/#/${APP_OWNER}/widget/QueryApi.${appPath}?selectedIndexerPath=${accountId}/${indexerName}&view=editor-window`;
const statusUrl = `https://near.org/#/${APP_OWNER}/widget/QueryApi.${appPath}?selectedIndexerPath=${accountId}/${indexerName}&view=indexer-status`;
// const playgroundLink = `https://near.org/#/${APP_OWNER}/widget/QueryApi.App?selectedIndexerPath=${accountId}/${indexerName}&view=editor-window&tab=playground`;
const playgroundLink = `https://cloud.hasura.io/public/graphiql?endpoint=${GRAPHQL_ENDPOINT}/v1/graphql&header=x-hasura-role%3A${accountId.replaceAll(
const editUrl = `https://near.org/#/${REPL_ACCOUNT_ID}/widget/QueryApi.App?selectedIndexerPath=${accountId}/${indexerName}&view=editor-window`;
const statusUrl = `https://near.org/#/${REPL_ACCOUNT_ID}/widget/QueryApi.App?selectedIndexerPath=${accountId}/${indexerName}&view=indexer-status`;
const playgroundLink = `https://cloud.hasura.io/public/graphiql?endpoint=${REPL_GRAPHQL_ENDPOINT}/v1/graphql&header=x-hasura-role%3A${accountId.replaceAll(
".",
"_"
)}`;
Expand Down Expand Up @@ -390,7 +379,7 @@ return (
<Main>
<Section active={state.activeTab === "indexers"}>
<NavBarLogo
href={`https://near.org/#/${APP_OWNER}/widget/QueryApi.${appPath}`}
href={`https://near.org/#/${REPL_ACCOUNT_ID}/widget/QueryApi.App`}
title="QueryApi"
onClick={() => selectTab("indexers")}
>
Expand All @@ -410,7 +399,7 @@ return (

<div>
<ButtonLink
href={`/#/${APP_OWNER}/widget/QueryApi.${appPath}/?view=create-new-indexer`}
href={`/#/${REPL_ACCOUNT_ID}/widget/QueryApi.App/?view=create-new-indexer`}
style={{ "margin-top": "10px" }}
onClick={() => {
State.update({
Expand All @@ -429,13 +418,7 @@ return (
</H2>
)}
<Widget
src={`${APP_OWNER}/widget/QueryApi.IndexerExplorer`}
props={{
GRAPHQL_ENDPOINT,
REGISTRY_CONTRACT_ID,
APP_OWNER,
appPath,
}}
src={`${REPL_ACCOUNT_ID}/widget/QueryApi.IndexerExplorer`}
/>
</div>
</Section>
Expand All @@ -447,16 +430,12 @@ return (
{state.activeTab === "create-new-indexer" && (
<div>
<Widget
src={`${APP_OWNER}/widget/QueryApi.Editor`}
src={`${REPL_ACCOUNT_ID}/widget/QueryApi.Editor`}
props={{
indexerName:
selected_indexerName ?? state.indexers[0].indexerName,
accountId: selected_accountId ?? state.indexers[0].accountId,
path: "create-new-indexer",
EXTERNAL_APP_URL,
REGISTRY_CONTRACT_ID,
GRAPHQL_ENDPOINT,
APP_OWNER,
}}
/>
</div>
Expand All @@ -476,15 +455,11 @@ return (
selected_indexerName ?? state.indexers[0].indexerName
)}
<Widget
src={`${APP_OWNER}/widget/QueryApi.IndexerStatus`}
src={`${REPL_ACCOUNT_ID}/widget/QueryApi.IndexerStatus`}
props={{
indexer_name:
selected_indexerName ?? state.indexers[0].indexerName,
accountId: selected_accountId ?? state.indexers[0].accountId,
EXTERNAL_APP_URL,
REGISTRY_CONTRACT_ID,
GRAPHQL_ENDPOINT,
APP_OWNER,
}}
/>
</div>
Expand All @@ -504,17 +479,13 @@ return (
<H2>{`${state.indexers[0].accountId}/${state.indexers[0].indexerName}`}</H2>
))}
<Widget
src={`${APP_OWNER}/widget/QueryApi.Editor`}
src={`${REPL_ACCOUNT_ID}/widget/QueryApi.Editor`}
props={{
indexerName:
selected_indexerName ?? state.indexers[0].indexerName,
accountId: selected_accountId ?? state.indexers[0].accountId,
path: "query-api-editor",
tab: props.tab,
EXTERNAL_APP_URL,
REGISTRY_CONTRACT_ID,
GRAPHQL_ENDPOINT,
APP_OWNER,
}}
/>
</div>
Expand All @@ -528,16 +499,12 @@ return (
<H2>{`${state.indexers[0].accountId}/${state.indexers[0].indexerName}`}</H2>
))}
<Widget
src={`${APP_OWNER}/widget/QueryApi.Editor`}
src={`${REPL_ACCOUNT_ID}/widget/QueryApi.Editor`}
props={{
indexerName:
selected_indexerName ?? state.indexers[0].indexerName,
accountId: selected_accountId ?? state.indexers[0].accountId,
path: "create-new-indexer",
EXTERNAL_APP_URL,
REGISTRY_CONTRACT_ID,
GRAPHQL_ENDPOINT,
APP_OWNER,
}}
/>
</div>
Expand Down
12 changes: 4 additions & 8 deletions frontend/widgets/src/QueryApi.Editor.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
const path = props.path || "query-api-editor";
const tab = props.tab || "";
const REGISTRY_CONTRACT_ID =
props.REGISTRY_CONTRACT_ID || "queryapi.dataplatform.near";
let accountId = props.accountId || context.accountId;
let externalAppUrl =
props.EXTERNAL_APP_URL || "https://queryapi-frontend-24ktefolwq-ew.a.run.app";
externalAppUrl += `/${path}?accountId=${accountId}`;
// let externalAppUrl = `http://localhost:3000/${path}?accountId=${accountId}`;
let externalAppUrl = `${REPL_EXTERNAL_APP_URL}/${path}?accountId=${accountId}`;

if (props.indexerName) {
externalAppUrl += `&indexerName=${props.indexerName}`;
Expand All @@ -30,7 +25,7 @@ const registerFunctionHandler = (request, response) => {
const jsonFilter = `{"indexer_rule_kind":"Action","matching_rule":{"rule":"ACTION_ANY","affected_account_id":"${contractFilter || "social.near"}","status":"SUCCESS"}}`

Near.call(
REGISTRY_CONTRACT_ID,
`${REPL_REGISTRY_CONTRACT_ID}`,
"register_indexer_function",
{
function_name: indexerName,
Expand All @@ -47,14 +42,15 @@ let deleteIndexer = (request) => {
const { indexerName } = request.payload;
const gas = 200000000000000;
Near.call(
REGISTRY_CONTRACT_ID,
`${REPL_REGISTRY_CONTRACT_ID}`,
"remove_indexer_function",
{
function_name: indexerName,
},
gas
);
};

/**
* Request Handlers here
*/
Expand Down
12 changes: 3 additions & 9 deletions frontend/widgets/src/QueryApi.IndexerCard.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
const accountId = props.accountId || context.accountId;
const indexerName = props.indexerName;
const GRAPHQL_ENDPOINT =
props.GRAPHQL_ENDPOINT ||
"https://queryapi-hasura-graphql-24ktefolwq-ew.a.run.app";
const APP_OWNER = props.APP_OWNER || "dataplatform.near";
const appPath = props.appPath || "App";
const editUrl = `https://near.org/#/${APP_OWNER}/widget/QueryApi.${appPath}?selectedIndexerPath=${accountId}/${indexerName}&view=editor-window`;
const statusUrl = `https://near.org/#/${APP_OWNER}/widget/QueryApi.${appPath}?selectedIndexerPath=${accountId}/${indexerName}&view=indexer-status`;
// const playgroundLink = `https://near.org/#/${APP_OWNER}/widget/QueryApi.App?selectedIndexerPath=${accountId}/${indexerName}&view=editor-window&tab=playground`;
const playgroundLink = `https://cloud.hasura.io/public/graphiql?endpoint=${GRAPHQL_ENDPOINT}/v1/graphql&header=x-hasura-role%3A${accountId.replaceAll(
const editUrl = `https://near.org/#/${REPL_ACCOUNT_ID}/widget/QueryApi.App?selectedIndexerPath=${accountId}/${indexerName}&view=editor-window`;
const statusUrl = `https://near.org/#/${REPL_ACCOUNT_ID}/widget/QueryApi.App?selectedIndexerPath=${accountId}/${indexerName}&view=indexer-status`;
const playgroundLink = `https://cloud.hasura.io/public/graphiql?endpoint=${REPL_GRAPHQL_ENDPOINT}/v1/graphql&header=x-hasura-role%3A${accountId.replaceAll(
".",
"_"
)}`;
Expand Down
18 changes: 3 additions & 15 deletions frontend/widgets/src/QueryApi.IndexerExplorer.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
const limitPerPage = 5;
const REGISTRY_CONTRACT_ID =
props.REGISTRY_CONTRACT_ID || "queryapi.dataplatform.near";
let APP_OWNER = props.APP_OWNER || "dev-queryapi.dataplatform.near";
const GRAPHQL_ENDPOINT =
props.GRAPHQL_ENDPOINT ||
"https://queryapi-hasura-graphql-24ktefolwq-ew.a.run.app";
let totalIndexers = 0;
const accountId = context.accountId;
State.init({
Expand All @@ -21,7 +15,7 @@ if (props.tab && props.tab !== state.selectedTab) {
});
}

Near.asyncView(REGISTRY_CONTRACT_ID, "list_indexer_functions").then((data) => {
Near.asyncView(`${REPL_REGISTRY_CONTRACT_ID}`, "list_indexer_functions").then((data) => {
const indexers = [];
const total_indexers = 0;
Object.keys(data.All).forEach((accountId) => {
Expand Down Expand Up @@ -242,13 +236,10 @@ return (
{state.all_indexers.map((indexer, i) => (
<Item>
<Widget
src="dev-queryapi.dataplatform.near/widget/QueryApi.IndexerCard"
src={`${REPL_ACCOUNT_ID}/widget/QueryApi.IndexerCard`}
props={{
accountId: indexer.accountId,
indexerName: indexer.indexerName,
APP_OWNER: APP_OWNER,
GRAPHQL_ENDPOINT,
appPath: props.appPath,
}}
/>
</Item>
Expand All @@ -275,13 +266,10 @@ return (
{state.my_indexers.map((indexer, i) => (
<Item>
<Widget
src="dev-queryapi.dataplatform.near/widget/QueryApi.IndexerCard"
src={`${REPL_ACCOUNT_ID}/widget/QueryApi.IndexerCard`}
props={{
accountId: indexer.accountId,
indexerName: indexer.indexerName,
APP_OWNER: APP_OWNER,
GRAPHQL_ENDPOINT,
appPath: props.appPath,
}}
/>
</Item>
Expand Down
8 changes: 3 additions & 5 deletions frontend/widgets/src/QueryApi.IndexerStatus.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
//props indexer_name
const indexer_name = props.indexer_name;

const GRAPHQL_ENDPOINT =
props.GRAPHQL_ENDPOINT ||
"https://queryapi-hasura-graphql-24ktefolwq-ew.a.run.app";
const LIMIT = 20;
const accountId = props.accountId || context.accountId;

const H2 = styled.h2`
font-size: 19px;
line-height: 22px;
Expand Down Expand Up @@ -110,7 +108,7 @@ State.init({
});

function fetchGraphQL(operationsDoc, operationName, variables) {
return asyncFetch(`${GRAPHQL_ENDPOINT}/v1/graphql`, {
return asyncFetch(`${REPL_GRAPHQL_ENDPOINT}/v1/graphql`, {
method: "POST",
body: JSON.stringify({
query: operationsDoc,
Expand All @@ -121,7 +119,7 @@ function fetchGraphQL(operationsDoc, operationName, variables) {
}

const createGraphQLLink = () => {
const queryLink = `https://cloud.hasura.io/public/graphiql?endpoint=${GRAPHQL_ENDPOINT}/v1/graphql&query=query+IndexerQuery+%7B%0A++indexer_state%28where%3A+%7Bfunction_name%3A+%7B_eq%3A+%22function_placeholder%22%7D%7D%29+%7B%0A++++function_name%0A++++current_block_height%0A++%7D%0A++indexer_log_entries%28%0A++++where%3A+%7Bfunction_name%3A+%7B_eq%3A+%22function_placeholder%22%7D%7D%0A++++order_by%3A+%7B+timestamp%3A+desc%7D%0A++%29+%7B%0A++++function_name%0A++++id%0A++++message%0A++++timestamp%0A++%7D%0A%7D%0A`;
const queryLink = `https://cloud.hasura.io/public/graphiql?endpoint=${REPL_GRAPHQL_ENDPOINT}/v1/graphql&query=query+IndexerQuery+%7B%0A++indexer_state%28where%3A+%7Bfunction_name%3A+%7B_eq%3A+%22function_placeholder%22%7D%7D%29+%7B%0A++++function_name%0A++++current_block_height%0A++%7D%0A++indexer_log_entries%28%0A++++where%3A+%7Bfunction_name%3A+%7B_eq%3A+%22function_placeholder%22%7D%7D%0A++++order_by%3A+%7B+timestamp%3A+desc%7D%0A++%29+%7B%0A++++function_name%0A++++id%0A++++message%0A++++timestamp%0A++%7D%0A%7D%0A`;
return queryLink.replaceAll(
"function_placeholder",
`${accountId}/${indexer_name}`
Expand Down
Loading