From 73be8dc5b0beb1888afc03ad1a9053e92bb62343 Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:06:15 -0800 Subject: [PATCH 01/14] Add API key everywhere Move APTOS_NETWORK to the SDK and have the frontend import it Select the API key by the network type instead of having to change it for each environment --- src/typescript/frontend/.eslintignore | 1 + .../src/components/charts/PrivateChart.tsx | 5 ++- .../frontend/src/context/providers.tsx | 6 +++- src/typescript/frontend/src/lib/env.ts | 15 ++------ .../frontend/src/lib/utils/aptos-client.ts | 8 +++-- src/typescript/sdk/src/const.ts | 35 +++++++++++++++++-- .../src/emojicoin_dot_fun/aptos-framework.ts | 9 ++--- .../emojicoin_dot_fun/emojicoin-dot-fun.ts | 19 +++++----- src/typescript/sdk/src/utils/aptos-client.ts | 18 +++++----- .../tests/e2e/queries/client/submit.test.ts | 23 +++++++++++- 10 files changed, 94 insertions(+), 45 deletions(-) diff --git a/src/typescript/frontend/.eslintignore b/src/typescript/frontend/.eslintignore index 429512ba7..655d36222 100644 --- a/src/typescript/frontend/.eslintignore +++ b/src/typescript/frontend/.eslintignore @@ -3,3 +3,4 @@ dist/ .next/ public/static/ tests/e2e/global.*.ts +playwright-report/ diff --git a/src/typescript/frontend/src/components/charts/PrivateChart.tsx b/src/typescript/frontend/src/components/charts/PrivateChart.tsx index dc0cb2552..ff10a9499 100644 --- a/src/typescript/frontend/src/components/charts/PrivateChart.tsx +++ b/src/typescript/frontend/src/components/charts/PrivateChart.tsx @@ -28,11 +28,10 @@ import path from "path"; import { emojisToName } from "lib/utils/emojis-to-name-or-symbol"; import { useEventStore } from "context/event-store-context"; import { getPeriodStartTimeFromTime } from "@sdk/utils"; -import { getAptosConfig } from "lib/utils/aptos-client"; +import { getAptos } from "lib/utils/aptos-client"; import { getSymbolEmojisInString, symbolToEmojis, toMarketEmojiData } from "@sdk/emoji_data"; import { type PeriodicStateEventModel, type MarketMetadataModel } from "@sdk/indexer-v2/types"; import { getMarketResource } from "@sdk/markets"; -import { Aptos } from "@aptos-labs/ts-sdk"; import { periodEnumToRawDuration, Trigger } from "@sdk/const"; import { type LatestBar, @@ -184,7 +183,7 @@ export const Chart = (props: ChartContainerProps) => { // Also, we specifically call this client-side because the server will get rate-limited if we call the // fullnode from the server for each client. const marketResource = await getMarketResource({ - aptos: new Aptos(getAptosConfig()), + aptos: getAptos(), marketAddress: props.marketAddress, }); diff --git a/src/typescript/frontend/src/context/providers.tsx b/src/typescript/frontend/src/context/providers.tsx index 4de51669c..cccbec7e7 100644 --- a/src/typescript/frontend/src/context/providers.tsx +++ b/src/typescript/frontend/src/context/providers.tsx @@ -28,6 +28,7 @@ import { RiseWallet } from "@rise-wallet/wallet-adapter"; import { MartianWallet } from "@martianwallet/aptos-wallet-adapter"; import { EmojiPickerProvider } from "./emoji-picker-context/EmojiPickerContextProvider"; import { isMobile, isTablet } from "react-device-detect"; +import { APTOS_API_KEY } from "@sdk/const"; enableMapSet(); @@ -50,7 +51,10 @@ const ThemedApp: React.FC<{ children: React.ReactNode }> = ({ children }) => { diff --git a/src/typescript/frontend/src/lib/env.ts b/src/typescript/frontend/src/lib/env.ts index 3205b8af0..4087e485b 100644 --- a/src/typescript/frontend/src/lib/env.ts +++ b/src/typescript/frontend/src/lib/env.ts @@ -1,7 +1,7 @@ -import { type Network } from "@aptos-labs/wallet-adapter-react"; import packageInfo from "../../package.json"; import { parse } from "semver"; import { type AccountAddressString } from "@sdk/emojicoin_dot_fun"; +import { APTOS_NETWORK as SDK_APTOS_NETWORK } from "@sdk/const"; export type Links = { x: string; @@ -10,7 +10,7 @@ export type Links = { tos: string; }; -let APTOS_NETWORK: Network; +const APTOS_NETWORK = SDK_APTOS_NETWORK; let INTEGRATOR_ADDRESS: AccountAddressString; let INTEGRATOR_FEE_RATE_BPS: number; let BROKER_URL: string; @@ -22,17 +22,6 @@ export const LINKS: Links | undefined = const IS_ALLOWLIST_ENABLED: boolean = process.env.NEXT_PUBLIC_IS_ALLOWLIST_ENABLED === "true"; -if (process.env.NEXT_PUBLIC_APTOS_NETWORK) { - const network = process.env.NEXT_PUBLIC_APTOS_NETWORK; - if (["mainnet", "testnet", "devnet", "local", "custom", "docker"].includes(network)) { - APTOS_NETWORK = network as Network; - } else { - throw new Error(`Invalid network: ${network}`); - } -} else { - throw new Error("Environment variable NEXT_PUBLIC_APTOS_NETWORK is undefined."); -} - if (process.env.NEXT_PUBLIC_INTEGRATOR_ADDRESS) { INTEGRATOR_ADDRESS = process.env.NEXT_PUBLIC_INTEGRATOR_ADDRESS as AccountAddressString; } else { diff --git a/src/typescript/frontend/src/lib/utils/aptos-client.ts b/src/typescript/frontend/src/lib/utils/aptos-client.ts index b6f2bb710..2adbc8b45 100644 --- a/src/typescript/frontend/src/lib/utils/aptos-client.ts +++ b/src/typescript/frontend/src/lib/utils/aptos-client.ts @@ -2,13 +2,16 @@ /* eslint-disable @typescript-eslint/no-var-requires */ import { NetworkToFaucetAPI, NetworkToIndexerAPI, NetworkToNodeAPI } from "@aptos-labs/ts-sdk"; import { Aptos, AptosConfig, NetworkToNetworkName } from "@aptos-labs/ts-sdk"; +import { APTOS_CONFIG } from "@sdk/utils/aptos-client"; import { APTOS_NETWORK } from "lib/env"; const toDockerUrl = (url: string) => url.replace("127.0.0.1", "host.docker.internal"); -// Get an Aptos config based off of the network environment variables. +// Get an Aptos config based off of the network environment variables and the default APTOS_CONFIG +// client configuration/settings. export const getAptosConfig = (): AptosConfig => { const networkString = APTOS_NETWORK; + const clientConfig = APTOS_CONFIG; if (networkString === "local" && typeof window === "undefined") { const fs = require("node:fs"); if (fs.existsSync("/.dockerenv")) { @@ -17,6 +20,7 @@ export const getAptosConfig = (): AptosConfig => { fullnode: toDockerUrl(NetworkToNodeAPI["local"]), indexer: toDockerUrl(NetworkToIndexerAPI["local"]), faucet: toDockerUrl(NetworkToFaucetAPI["local"]), + clientConfig, }); } } @@ -27,7 +31,7 @@ export const getAptosConfig = (): AptosConfig => { if (!network) { throw new Error(`Invalid network: ${networkString}`); } - return new AptosConfig({ network, fullnode, indexer, faucet }); + return new AptosConfig({ network, fullnode, indexer, faucet, clientConfig }); }; // Get an Aptos client based off of the network environment variables. diff --git a/src/typescript/sdk/src/const.ts b/src/typescript/sdk/src/const.ts index d936c75ac..38adc8232 100644 --- a/src/typescript/sdk/src/const.ts +++ b/src/typescript/sdk/src/const.ts @@ -1,4 +1,10 @@ -import { AccountAddress, APTOS_COIN, parseTypeTag } from "@aptos-labs/ts-sdk"; +import { + AccountAddress, + APTOS_COIN, + Network, + NetworkToNetworkName, + parseTypeTag, +} from "@aptos-labs/ts-sdk"; import Big from "big.js"; import { type ValueOf } from "./utils/utility-types"; import { type DatabaseStructType } from "./indexer-v2/types/json-types"; @@ -8,13 +14,17 @@ if ( !process.env.NEXT_PUBLIC_MODULE_ADDRESS || !process.env.NEXT_PUBLIC_REWARDS_MODULE_ADDRESS || !process.env.NEXT_PUBLIC_INTEGRATOR_ADDRESS || - !process.env.NEXT_PUBLIC_INTEGRATOR_FEE_RATE_BPS + !process.env.NEXT_PUBLIC_INTEGRATOR_FEE_RATE_BPS || + !process.env.NEXT_PUBLIC_APTOS_API_KEY || + !process.env.NEXT_PUBLIC_APTOS_NETWORK ) { const missing = [ ["NEXT_PUBLIC_MODULE_ADDRESS", process.env.NEXT_PUBLIC_MODULE_ADDRESS], ["NEXT_PUBLIC_REWARDS_MODULE_ADDRESS", process.env.NEXT_PUBLIC_REWARDS_MODULE_ADDRESS], ["NEXT_PUBLIC_INTEGRATOR_ADDRESS", process.env.NEXT_PUBLIC_INTEGRATOR_ADDRESS], ["NEXT_PUBLIC_INTEGRATOR_FEE_RATE_BPS", process.env.NEXT_PUBLIC_INTEGRATOR_FEE_RATE_BPS], + ["NEXT_PUBLIC_APTOS_API_KEY", process.env.NEXT_PUBLIC_APTOS_API_KEY], + ["NEXT_PUBLIC_APTOS_NETWORK", process.env.NEXT_PUBLIC_APTOS_NETWORK], ].filter(([_, value]) => !value); missing.forEach(([key, _]) => { console.error(`Missing environment variables ${key}`); @@ -26,6 +36,27 @@ if ( ); } +const network = process.env.NEXT_PUBLIC_APTOS_NETWORK; +export const APTOS_NETWORK = NetworkToNetworkName[network]; +if (!APTOS_NETWORK) { + throw new Error(`Invalid network: ${network}`); +} + +const allAPIKeys: Record = { + [Network.LOCAL]: process.env.NEXT_PUBLIC_LOCAL_APTOS_API_KEY, + [Network.DEVNET]: process.env.NEXT_PUBLIC_DEVNET_APTOS_API_KEY, + [Network.TESTNET]: process.env.NEXT_PUBLIC_TESTNET_APTOS_API_KEY, + [Network.MAINNET]: process.env.NEXT_PUBLIC_MAINNET_APTOS_API_KEY, + [Network.CUSTOM]: process.env.NEXT_PUBLIC_CUSTOM_APTOS_API_KEY, +}; +export const apiKey = allAPIKeys[APTOS_NETWORK]; +if (typeof apiKey === "undefined") { + throw new Error(`Invalid API key set for the network: ${APTOS_NETWORK}: ${apiKey}`); +} +// Select the API key from the list of env API keys. This means we don't have to change the env +// var for API keys when changing environments- we just need to provide them all every time, which +// is much simpler. +export const APTOS_API_KEY = apiKey; export const MODULE_ADDRESS = (() => AccountAddress.from(process.env.NEXT_PUBLIC_MODULE_ADDRESS))(); export const REWARDS_MODULE_ADDRESS = (() => AccountAddress.from(process.env.NEXT_PUBLIC_REWARDS_MODULE_ADDRESS))(); diff --git a/src/typescript/sdk/src/emojicoin_dot_fun/aptos-framework.ts b/src/typescript/sdk/src/emojicoin_dot_fun/aptos-framework.ts index a0a8f21be..61e246e5b 100644 --- a/src/typescript/sdk/src/emojicoin_dot_fun/aptos-framework.ts +++ b/src/typescript/sdk/src/emojicoin_dot_fun/aptos-framework.ts @@ -8,7 +8,7 @@ import { type AptosConfig, type InputGenerateTransactionOptions, buildTransaction, - Aptos, + type Aptos, type Account, type WaitForTransactionOptions, type UserTransactionResponse, @@ -22,6 +22,7 @@ import { ViewFunctionPayloadBuilder, } from "./payload-builders"; import { type TypeTagInput } from "."; +import { getAptosClient } from "../utils/aptos-client"; export type MintPayloadMoveArguments = { dstAddr: AccountAddress; @@ -89,7 +90,7 @@ export class Mint extends EntryFunctionPayloadBuilder { options, feePayerAddress: feePayer, }); - const aptos = new Aptos(aptosConfig); + const { aptos } = getAptosClient(aptosConfig); return new EntryFunctionTransactionBuilder(payloadBuilder, aptos, rawTransactionInput); } @@ -189,7 +190,7 @@ export class BatchTransferCoins extends EntryFunctionPayloadBuilder { options, feePayerAddress: feePayer, }); - const aptos = new Aptos(aptosConfig); + const { aptos } = getAptosClient(aptosConfig); return new EntryFunctionTransactionBuilder(payloadBuilder, aptos, rawTransactionInput); } @@ -290,7 +291,7 @@ export class TransferCoins extends EntryFunctionPayloadBuilder { options, feePayerAddress: feePayer, }); - const aptos = new Aptos(aptosConfig); + const { aptos } = getAptosClient(aptosConfig); return new EntryFunctionTransactionBuilder(payloadBuilder, aptos, rawTransactionInput); } diff --git a/src/typescript/sdk/src/emojicoin_dot_fun/emojicoin-dot-fun.ts b/src/typescript/sdk/src/emojicoin_dot_fun/emojicoin-dot-fun.ts index 20f136eb6..69ad70d93 100644 --- a/src/typescript/sdk/src/emojicoin_dot_fun/emojicoin-dot-fun.ts +++ b/src/typescript/sdk/src/emojicoin_dot_fun/emojicoin-dot-fun.ts @@ -7,7 +7,7 @@ import { U8, Bool, type Account, - Aptos, + type Aptos, type AptosConfig, type AccountAddressInput, type HexInput, @@ -35,6 +35,7 @@ import { } from "./payload-builders"; import { MODULE_ADDRESS, REWARDS_MODULE_ADDRESS } from "../const"; import type JsonTypes from "../types/json-types"; +import { getAptosClient } from "../utils/aptos-client"; export type ChatPayloadMoveArguments = { marketAddress: AccountAddress; @@ -112,7 +113,7 @@ export class Chat extends EntryFunctionPayloadBuilder { options, feePayerAddress: feePayer, }); - const aptos = new Aptos(aptosConfig); + const { aptos } = getAptosClient(aptosConfig); return new EntryFunctionTransactionBuilder(payloadBuilder, aptos, rawTransactionInput); } @@ -219,7 +220,7 @@ export class ProvideLiquidity extends EntryFunctionPayloadBuilder { options, feePayerAddress: feePayer, }); - const aptos = new Aptos(aptosConfig); + const { aptos } = getAptosClient(aptosConfig); return new EntryFunctionTransactionBuilder(payloadBuilder, aptos, rawTransactionInput); } @@ -307,7 +308,7 @@ export class RegisterMarket extends EntryFunctionPayloadBuilder { }): Promise<{ data: { amount: number; unitPrice: number }; error: boolean }> { const { aptosConfig } = args; - const aptos = new Aptos(aptosConfig); + const { aptos } = getAptosClient(aptosConfig); const rawTransaction = await this.builder({ ...args, integrator: AccountAddress.ONE, @@ -347,7 +348,7 @@ export class RegisterMarket extends EntryFunctionPayloadBuilder { options, feePayerAddress: feePayer, }); - const aptos = new Aptos(aptosConfig); + const { aptos } = getAptosClient(aptosConfig); return new EntryFunctionTransactionBuilder(payloadBuilder, aptos, rawTransactionInput); } @@ -452,7 +453,7 @@ export class RemoveLiquidity extends EntryFunctionPayloadBuilder { options, feePayerAddress: feePayer, }); - const aptos = new Aptos(aptosConfig); + const { aptos } = getAptosClient(aptosConfig); return new EntryFunctionTransactionBuilder(payloadBuilder, aptos, rawTransactionInput); } @@ -584,7 +585,7 @@ export class Swap extends EntryFunctionPayloadBuilder { options, feePayerAddress: feePayer, }); - const aptos = new Aptos(aptosConfig); + const { aptos } = getAptosClient(aptosConfig); return new EntryFunctionTransactionBuilder(payloadBuilder, aptos, rawTransactionInput); } @@ -633,7 +634,7 @@ export class Swap extends EntryFunctionPayloadBuilder { }): Promise { const { aptosConfig } = args; - const aptos = new Aptos(aptosConfig); + const { aptos } = getAptosClient(aptosConfig); const rawTransaction = await this.builder({ ...args, integrator: AccountAddress.ONE, @@ -733,7 +734,7 @@ export class SwapWithRewards extends EntryFunctionPayloadBuilder { options, feePayerAddress: feePayer, }); - const aptos = new Aptos(aptosConfig); + const { aptos } = getAptosClient(aptosConfig); return new EntryFunctionTransactionBuilder(payloadBuilder, aptos, rawTransactionInput); } diff --git a/src/typescript/sdk/src/utils/aptos-client.ts b/src/typescript/sdk/src/utils/aptos-client.ts index ac96e421e..27ffd317e 100644 --- a/src/typescript/sdk/src/utils/aptos-client.ts +++ b/src/typescript/sdk/src/utils/aptos-client.ts @@ -1,22 +1,20 @@ -import { Aptos, AptosConfig, Network, NetworkToNetworkName } from "@aptos-labs/ts-sdk"; +import { Aptos, AptosConfig, type ClientConfig } from "@aptos-labs/ts-sdk"; +import { APTOS_API_KEY, APTOS_NETWORK } from "../const"; + +export const APTOS_CONFIG: Partial = { + API_KEY: APTOS_API_KEY, +}; export function getAptosClient(additionalConfig?: Partial): { aptos: Aptos; config: AptosConfig; } { - const network = getAptosNetwork(); + const network = APTOS_NETWORK; const config = new AptosConfig({ network, ...additionalConfig, + ...APTOS_CONFIG, }); const aptos = new Aptos(config); return { aptos, config }; } - -export function getAptosNetwork(): Network { - const networkRaw = process.env.NEXT_PUBLIC_APTOS_NETWORK; - if (!networkRaw) { - throw new Error("NEXT_PUBLIC_APTOS_NETWORK environment variable is not set."); - } - return networkRaw ? NetworkToNetworkName[networkRaw] : Network.LOCAL; -} diff --git a/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts b/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts index e5c0c12d7..eb0d4f34b 100644 --- a/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts +++ b/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts @@ -1,4 +1,5 @@ import { + APTOS_API_KEY, getEmojicoinMarketAddressAndTypeTags, INTEGRATOR_ADDRESS, INTEGRATOR_FEE_RATE_BPS, @@ -20,7 +21,7 @@ import { Network, } from "@aptos-labs/ts-sdk"; import { EXACT_TRANSITION_INPUT_AMOUNT } from "../../../../src/utils/test/helpers"; -import { getAptosNetwork } from "../../../../src/utils/aptos-client"; +import { getAptosClient, getAptosNetwork } from "../../../../src/utils/aptos-client"; import { calculatePeriodBoundariesCrossed } from "../../../../src/utils/test"; jest.setTimeout(15000); @@ -103,6 +104,26 @@ describe("all submission types for the emojicoin client", () => { expect(emojicoinClient.aptos.config.network).toEqual(Network.TESTNET); }); + it("sets the API key in the aptos client configuration", () => { + const config = new AptosConfig({ + network: Network.TESTNET, + }); + const aptos = new Aptos(config); + const emojicoinClient = new EmojicoinClient({ aptos }); + expect(aptos.config.clientConfig?.API_KEY).toEqual(APTOS_API_KEY); + expect(emojicoinClient.aptos.config.clientConfig?.API_KEY).toEqual(APTOS_API_KEY); + }); + + it("sets the API key in the client returned by getAptos()", () => { + const config = new AptosConfig({ + network: Network.TESTNET, + }); + const { aptos } = getAptosClient(config); + const emojicoinClient = new EmojicoinClient({ aptos }); + expect(aptos.config.clientConfig?.API_KEY).toEqual(APTOS_API_KEY); + expect(emojicoinClient.aptos.config.clientConfig?.API_KEY).toEqual(APTOS_API_KEY); + }); + it("creates the aptos client with the correct default configuration settings", () => { expect(emojicoin.aptos.config.network).toEqual(process.env.NEXT_PUBLIC_APTOS_NETWORK); expect(emojicoin.aptos.config.network).toEqual(getAptosNetwork()); From 0b20534c10165e343100d4107c9f4ee48aa1f8fd Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:23:23 -0800 Subject: [PATCH 02/14] Add .env values to the frontend dockerfile and example .env files --- src/docker/compose.yaml | 5 +++++ src/docker/example.local.env | 7 +++++++ src/docker/example.testnet.env | 7 +++++++ src/docker/frontend/Dockerfile | 14 ++++++++++++-- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/docker/compose.yaml b/src/docker/compose.yaml index b16ae890f..f044a5c82 100644 --- a/src/docker/compose.yaml +++ b/src/docker/compose.yaml @@ -129,6 +129,11 @@ services: NEXT_PUBLIC_BROKER_URL: 'ws://host.docker.internal:${BROKER_PORT}' NEXT_PUBLIC_REWARDS_MODULE_ADDRESS: '${EMOJICOIN_REWARDS_MODULE_ADDRESS}' REVALIDATION_TIME: '${REVALIDATION_TIME}' + NEXT_PUBLIC_LOCAL_APTOS_API_KEY: '${FRONTEND_LOCAL_APTOS_API_KEY}' + NEXT_PUBLIC_CUSTOM_APTOS_API_KEY: '${FRONTEND_CUSTOM_APTOS_API_KEY}' + NEXT_PUBLIC_DEVNET_APTOS_API_KEY: '${FRONTEND_DEVNET_APTOS_API_KEY}' + NEXT_PUBLIC_TESTNET_APTOS_API_KEY: '${FRONTEND_TESTNET_APTOS_API_KEY}' + NEXT_PUBLIC_MAINNET_APTOS_API_KEY: '${FRONTEND_MAINNET_APTOS_API_KEY}' healthcheck: test: 'curl -f http://localhost:3001/ || exit 1' interval: '30s' diff --git a/src/docker/example.local.env b/src/docker/example.local.env index 268f5a1f2..ebe7d7bb8 100644 --- a/src/docker/example.local.env +++ b/src/docker/example.local.env @@ -77,3 +77,10 @@ FEE_RATE_BPS="100" # Secret hash seed. HASH_SEED="some random string that is not public" + +# Set the API keys for the various frontend networks. It is okay if these are exposed publicly. +FRONTEND_LOCAL_APTOS_API_KEY="" +FRONTEND_CUSTOM_APTOS_API_KEY="" +FRONTEND_DEVNET_APTOS_API_KEY="AG-MSPVZN9BNPNB6KWSPZN7GHSETJU2TFLHJ" +FRONTEND_TESTNET_APTOS_API_KEY="AG-FRGKQEVCNY5PDJKZBAVTVCPGEQ6YFUBBX" +FRONTEND_MAINNET_APTOS_API_KEY="AG-BAGXRD2QME5WFTBZVAR4BPA7M5EGTBRHQ" diff --git a/src/docker/example.testnet.env b/src/docker/example.testnet.env index 39df3c32c..144406d9d 100644 --- a/src/docker/example.testnet.env +++ b/src/docker/example.testnet.env @@ -64,3 +64,10 @@ FEE_RATE_BPS="100" # Secret hash seed. HASH_SEED="some random string that is not public" + +# Set the API keys for the various frontend networks. It is okay if these are exposed publicly. +FRONTEND_LOCAL_APTOS_API_KEY="" +FRONTEND_CUSTOM_APTOS_API_KEY="" +FRONTEND_DEVNET_APTOS_API_KEY="AG-MSPVZN9BNPNB6KWSPZN7GHSETJU2TFLHJ" +FRONTEND_TESTNET_APTOS_API_KEY="AG-FRGKQEVCNY5PDJKZBAVTVCPGEQ6YFUBBX" +FRONTEND_MAINNET_APTOS_API_KEY="AG-BAGXRD2QME5WFTBZVAR4BPA7M5EGTBRHQ" diff --git a/src/docker/frontend/Dockerfile b/src/docker/frontend/Dockerfile index 908e99374..7a3dddef9 100644 --- a/src/docker/frontend/Dockerfile +++ b/src/docker/frontend/Dockerfile @@ -19,7 +19,12 @@ ARG HASH_SEED \ NEXT_PUBLIC_REWARDS_MODULE_ADDRESS \ NEXT_PUBLIC_BROKER_URL \ REVALIDATION_TIME \ - EMOJICOIN_INDEXER_URL + EMOJICOIN_INDEXER_URL \ + NEXT_PUBLIC_LOCAL_APTOS_API_KEY \ + NEXT_PUBLIC_CUSTOM_APTOS_API_KEY \ + NEXT_PUBLIC_DEVNET_APTOS_API_KEY \ + NEXT_PUBLIC_TESTNET_APTOS_API_KEY \ + NEXT_PUBLIC_MAINNET_APTOS_API_KEY ENV HASH_SEED=$HASH_SEED \ NEXT_PUBLIC_APTOS_NETWORK=$NEXT_PUBLIC_APTOS_NETWORK \ NEXT_PUBLIC_INTEGRATOR_ADDRESS=$NEXT_PUBLIC_INTEGRATOR_ADDRESS \ @@ -29,7 +34,12 @@ ENV HASH_SEED=$HASH_SEED \ NEXT_PUBLIC_REWARDS_MODULE_ADDRESS=$NEXT_PUBLIC_REWARDS_MODULE_ADDRESS \ NEXT_PUBLIC_BROKER_URL=$NEXT_PUBLIC_BROKER_URL \ REVALIDATION_TIME=$REVALIDATION_TIME \ - EMOJICOIN_INDEXER_URL=$EMOJICOIN_INDEXER_URL + EMOJICOIN_INDEXER_URL=$EMOJICOIN_INDEXER_URL \ + NEXT_PUBLIC_LOCAL_APTOS_API_KEY=$FRONTEND_LOCAL_APTOS_API_KEY \ + NEXT_PUBLIC_CUSTOM_APTOS_API_KEY=$FRONTEND_CUSTOM_APTOS_API_KEY \ + NEXT_PUBLIC_DEVNET_APTOS_API_KEY=$FRONTEND_DEVNET_APTOS_API_KEY \ + NEXT_PUBLIC_TESTNET_APTOS_API_KEY=$FRONTEND_TESTNET_APTOS_API_KEY \ + NEXT_PUBLIC_MAINNET_APTOS_API_KEY=$FRONTEND_MAINNET_APTOS_API_KEY RUN ["bash", "-c", "pnpm install && pnpm run build:no-checks"] From 05679118edf727684f99efba64a865b62d19d7c6 Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:31:20 -0800 Subject: [PATCH 03/14] Remove check from array of checks in env checks in const.ts, since we check it later per network --- src/typescript/sdk/src/const.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/typescript/sdk/src/const.ts b/src/typescript/sdk/src/const.ts index 38adc8232..7ecf24f7c 100644 --- a/src/typescript/sdk/src/const.ts +++ b/src/typescript/sdk/src/const.ts @@ -15,7 +15,6 @@ if ( !process.env.NEXT_PUBLIC_REWARDS_MODULE_ADDRESS || !process.env.NEXT_PUBLIC_INTEGRATOR_ADDRESS || !process.env.NEXT_PUBLIC_INTEGRATOR_FEE_RATE_BPS || - !process.env.NEXT_PUBLIC_APTOS_API_KEY || !process.env.NEXT_PUBLIC_APTOS_NETWORK ) { const missing = [ @@ -23,7 +22,6 @@ if ( ["NEXT_PUBLIC_REWARDS_MODULE_ADDRESS", process.env.NEXT_PUBLIC_REWARDS_MODULE_ADDRESS], ["NEXT_PUBLIC_INTEGRATOR_ADDRESS", process.env.NEXT_PUBLIC_INTEGRATOR_ADDRESS], ["NEXT_PUBLIC_INTEGRATOR_FEE_RATE_BPS", process.env.NEXT_PUBLIC_INTEGRATOR_FEE_RATE_BPS], - ["NEXT_PUBLIC_APTOS_API_KEY", process.env.NEXT_PUBLIC_APTOS_API_KEY], ["NEXT_PUBLIC_APTOS_NETWORK", process.env.NEXT_PUBLIC_APTOS_NETWORK], ].filter(([_, value]) => !value); missing.forEach(([key, _]) => { From 0276c88e276018cde447ea784983ce0f7f07f9b6 Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:42:41 -0800 Subject: [PATCH 04/14] Remove `getAptosNetwork` from test --- src/typescript/sdk/tests/e2e/queries/client/submit.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts b/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts index eb0d4f34b..a73fa918f 100644 --- a/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts +++ b/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts @@ -1,5 +1,6 @@ import { APTOS_API_KEY, + APTOS_NETWORK, getEmojicoinMarketAddressAndTypeTags, INTEGRATOR_ADDRESS, INTEGRATOR_FEE_RATE_BPS, @@ -21,7 +22,7 @@ import { Network, } from "@aptos-labs/ts-sdk"; import { EXACT_TRANSITION_INPUT_AMOUNT } from "../../../../src/utils/test/helpers"; -import { getAptosClient, getAptosNetwork } from "../../../../src/utils/aptos-client"; +import { getAptosClient } from "../../../../src/utils/aptos-client"; import { calculatePeriodBoundariesCrossed } from "../../../../src/utils/test"; jest.setTimeout(15000); @@ -126,7 +127,7 @@ describe("all submission types for the emojicoin client", () => { it("creates the aptos client with the correct default configuration settings", () => { expect(emojicoin.aptos.config.network).toEqual(process.env.NEXT_PUBLIC_APTOS_NETWORK); - expect(emojicoin.aptos.config.network).toEqual(getAptosNetwork()); + expect(emojicoin.aptos.config.network).toEqual(APTOS_NETWORK); }); it("registers a market", async () => { From ec77d30cc38c0b261bd33444e3f1c8393027c68b Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:34:31 -0800 Subject: [PATCH 05/14] Add build time API key verification --- src/typescript/frontend/src/app/test/route.ts | 3 +++ .../frontend/src/app/verify_api_keys/page.tsx | 24 +++++++++++++++++++ src/typescript/sdk/src/const.ts | 4 ++-- 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 src/typescript/frontend/src/app/verify_api_keys/page.tsx diff --git a/src/typescript/frontend/src/app/test/route.ts b/src/typescript/frontend/src/app/test/route.ts index afee2db37..b2681c6c3 100644 --- a/src/typescript/frontend/src/app/test/route.ts +++ b/src/typescript/frontend/src/app/test/route.ts @@ -5,6 +5,9 @@ export const revalidate = 2; export const fetchCache = "default-cache"; export async function GET() { + if (process.env.NODE_ENV !== "test") { + return new NextResponse("-1"); + } const aptos = getAptos(); try { const version = await aptos.getLedgerInfo().then((res) => res.ledger_version); diff --git a/src/typescript/frontend/src/app/verify_api_keys/page.tsx b/src/typescript/frontend/src/app/verify_api_keys/page.tsx new file mode 100644 index 000000000..57a4985b5 --- /dev/null +++ b/src/typescript/frontend/src/app/verify_api_keys/page.tsx @@ -0,0 +1,24 @@ +import { AccountAddress } from "@aptos-labs/ts-sdk"; +import { APTOS_API_KEY } from "@sdk/const"; +import { getAptosClient } from "@sdk/utils/aptos-client"; + +export const dynamic = "force-static"; +export const revalidate = 600; +export const runtime = 'nodejs'; + +const VerifyApiKeys = async () => { + const { aptos } = getAptosClient(); + const accountAddress = AccountAddress.ONE; + let balance = 0; + try { + balance = await aptos.account.getAccountAPTAmount({ accountAddress }); + } catch (e) { + throw new Error(`Couldn't fetch ${accountAddress}'s balance. APTOS_API_KEY: ${APTOS_API_KEY}`); + } + + return ( +
{`Balance: ${balance}`}
+ ); +}; + +export default VerifyApiKeys; diff --git a/src/typescript/sdk/src/const.ts b/src/typescript/sdk/src/const.ts index 7ecf24f7c..6c27dfb0f 100644 --- a/src/typescript/sdk/src/const.ts +++ b/src/typescript/sdk/src/const.ts @@ -41,11 +41,11 @@ if (!APTOS_NETWORK) { } const allAPIKeys: Record = { - [Network.LOCAL]: process.env.NEXT_PUBLIC_LOCAL_APTOS_API_KEY, + [Network.LOCAL]: process.env.NEXT_PUBLIC_LOCAL_APTOS_API_KEY ?? "", + [Network.CUSTOM]: process.env.NEXT_PUBLIC_CUSTOM_APTOS_API_KEY ?? "", [Network.DEVNET]: process.env.NEXT_PUBLIC_DEVNET_APTOS_API_KEY, [Network.TESTNET]: process.env.NEXT_PUBLIC_TESTNET_APTOS_API_KEY, [Network.MAINNET]: process.env.NEXT_PUBLIC_MAINNET_APTOS_API_KEY, - [Network.CUSTOM]: process.env.NEXT_PUBLIC_CUSTOM_APTOS_API_KEY, }; export const apiKey = allAPIKeys[APTOS_NETWORK]; if (typeof apiKey === "undefined") { From ee26b2c4371f514c854df0aee0f26cf4d01697a5 Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:00:09 -0800 Subject: [PATCH 06/14] Have `build` use non-test env, have docker use test .env --- src/typescript/frontend/src/lib/env.ts | 12 ++++++++++-- src/typescript/frontend/src/lib/server-env.ts | 3 +-- src/typescript/package.json | 7 ++++--- src/typescript/turbo.json | 6 ++++++ 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/typescript/frontend/src/lib/env.ts b/src/typescript/frontend/src/lib/env.ts index 4087e485b..0e0d4efa9 100644 --- a/src/typescript/frontend/src/lib/env.ts +++ b/src/typescript/frontend/src/lib/env.ts @@ -1,7 +1,7 @@ import packageInfo from "../../package.json"; import { parse } from "semver"; import { type AccountAddressString } from "@sdk/emojicoin_dot_fun"; -import { APTOS_NETWORK as SDK_APTOS_NETWORK } from "@sdk/const"; +import { type Network } from "@aptos-labs/ts-sdk"; export type Links = { x: string; @@ -10,7 +10,15 @@ export type Links = { tos: string; }; -const APTOS_NETWORK = SDK_APTOS_NETWORK; +const network = process.env.NEXT_PUBLIC_APTOS_NETWORK; +const APTOS_NETWORK = network as Network; +// NOTE: We must check it this way instead of with `NetworkToNetworkName[APTOS_NETWORK]` because +// otherwise the @aptos-labs/ts-sdk package is included in the middleware.ts function and the edge +// runtime won't build properly. +if (!["local", "devnet", "testnet", "mainnet", "custom"].includes(APTOS_NETWORK)) { + throw new Error(`Invalid network: ${network}`); +} + let INTEGRATOR_ADDRESS: AccountAddressString; let INTEGRATOR_FEE_RATE_BPS: number; let BROKER_URL: string; diff --git a/src/typescript/frontend/src/lib/server-env.ts b/src/typescript/frontend/src/lib/server-env.ts index 38ea2332e..9d2966f02 100644 --- a/src/typescript/frontend/src/lib/server-env.ts +++ b/src/typescript/frontend/src/lib/server-env.ts @@ -1,6 +1,5 @@ import "server-only"; import { APTOS_NETWORK, IS_ALLOWLIST_ENABLED } from "./env"; -import { Network } from "@aptos-labs/ts-sdk"; import { EMOJICOIN_INDEXER_URL } from "@sdk/server/env"; if (typeof process.env.REVALIDATION_TIME === "undefined") { @@ -45,7 +44,7 @@ export const VPNAPI_IO_API_KEY: string = process.env.VPNAPI_IO_API_KEY!; export const PRE_LAUNCH_TEASER: boolean = process.env.PRE_LAUNCH_TEASER === "true"; if ( - APTOS_NETWORK === Network.LOCAL && + APTOS_NETWORK.toString() === "local" && !EMOJICOIN_INDEXER_URL.includes("localhost") && !EMOJICOIN_INDEXER_URL.includes("docker") ) { diff --git a/src/typescript/package.json b/src/typescript/package.json index 4e734dfab..25d3a5191 100644 --- a/src/typescript/package.json +++ b/src/typescript/package.json @@ -17,9 +17,10 @@ "keyv": "npm:@keyvhq/core@2.1.1" }, "scripts": { - "build": "pnpm i && pnpm load-env:test -- turbo run build", - "build:debug": "pnpm i && pnpm load-env:test -- turbo run build:debug", - "build:no-checks": "pnpm i && pnpm load-env:test -- turbo run build:no-checks", + "build": "pnpm i && pnpm load-env -- turbo run build", + "build:debug": "pnpm i && pnpm load-env -- turbo run build:debug", + "build:no-checks": "pnpm i && pnpm load-env -- turbo run build:no-checks", + "build:test": "pnpm i && pnpm load-env:test -- turbo run build:no-checks", "check": "turbo run check", "clean": "turbo run clean --no-cache --force && rm -rf .turbo", "clean:full": "pnpm run clean && rm -rf node_modules && rm -rf sdk/node_modules && rm -rf frontend/node_modules", diff --git a/src/typescript/turbo.json b/src/typescript/turbo.json index 7392f70bd..72a8f32db 100644 --- a/src/typescript/turbo.json +++ b/src/typescript/turbo.json @@ -27,6 +27,12 @@ ".next/**" ] }, + "build:test": { + "outputs": [ + "dist/**", + ".next/**" + ] + }, "check": { "outputs": [] }, From 46284e71a49a1b06867a68edafc90e373214f573 Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:10:09 -0800 Subject: [PATCH 07/14] Have the `EmojicoinClient` class use the hard coded aptos config no matter what --- src/typescript/sdk/src/client/emojicoin-client.ts | 9 ++++++--- src/typescript/sdk/src/const.ts | 2 +- .../sdk/tests/e2e/queries/client/submit.test.ts | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/typescript/sdk/src/client/emojicoin-client.ts b/src/typescript/sdk/src/client/emojicoin-client.ts index 3f936abea..f9f542fbd 100644 --- a/src/typescript/sdk/src/client/emojicoin-client.ts +++ b/src/typescript/sdk/src/client/emojicoin-client.ts @@ -1,12 +1,13 @@ import { AccountAddress, + Aptos, type Account, type UserTransactionResponse, type AccountAddressInput, - type Aptos, type TypeTag, type InputGenerateTransactionOptions, type WaitForTransactionOptions, + AptosConfig, } from "@aptos-labs/ts-sdk"; import { type ChatEmoji, type SymbolEmoji } from "../emoji_data/types"; import { EmojicoinDotFun, getEvents } from "../emojicoin_dot_fun"; @@ -21,7 +22,7 @@ import { import { type Events } from "../emojicoin_dot_fun/events"; import { getEmojicoinMarketAddressAndTypeTags } from "../markets"; import { type EventsModels, getEventsAsProcessorModelsFromResponse } from "../mini-processor"; -import { getAptosClient } from "../utils/aptos-client"; +import { APTOS_CONFIG, getAptosClient } from "../utils/aptos-client"; import { toChatMessageEntryFunctionArgs } from "../emoji_data"; import customExpect from "./expect"; import { DEFAULT_REGISTER_MARKET_GAS_OPTIONS, INTEGRATOR_ADDRESS } from "../const"; @@ -145,7 +146,9 @@ export class EmojicoinClient { integratorFeeRateBPs = 0, minOutputAmount = 1n, } = args ?? {}; - this.aptos = aptos; + // Create a client that always uses the static API_KEY config options. + const hardCodedConfig = new AptosConfig({ ...aptos.config, clientConfig: APTOS_CONFIG }); + this.aptos = new Aptos(hardCodedConfig); this.integrator = AccountAddress.from(integrator); this.integratorFeeRateBPs = Number(integratorFeeRateBPs); this.minOutputAmount = BigInt(minOutputAmount); diff --git a/src/typescript/sdk/src/const.ts b/src/typescript/sdk/src/const.ts index 6c27dfb0f..d3df6e94a 100644 --- a/src/typescript/sdk/src/const.ts +++ b/src/typescript/sdk/src/const.ts @@ -47,7 +47,7 @@ const allAPIKeys: Record = { [Network.TESTNET]: process.env.NEXT_PUBLIC_TESTNET_APTOS_API_KEY, [Network.MAINNET]: process.env.NEXT_PUBLIC_MAINNET_APTOS_API_KEY, }; -export const apiKey = allAPIKeys[APTOS_NETWORK]; +const apiKey = allAPIKeys[APTOS_NETWORK]; if (typeof apiKey === "undefined") { throw new Error(`Invalid API key set for the network: ${APTOS_NETWORK}: ${apiKey}`); } diff --git a/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts b/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts index a73fa918f..96445d79c 100644 --- a/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts +++ b/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts @@ -111,7 +111,7 @@ describe("all submission types for the emojicoin client", () => { }); const aptos = new Aptos(config); const emojicoinClient = new EmojicoinClient({ aptos }); - expect(aptos.config.clientConfig?.API_KEY).toEqual(APTOS_API_KEY); + expect(aptos.config.clientConfig?.API_KEY ?? "").toEqual(APTOS_API_KEY); expect(emojicoinClient.aptos.config.clientConfig?.API_KEY).toEqual(APTOS_API_KEY); }); @@ -121,7 +121,7 @@ describe("all submission types for the emojicoin client", () => { }); const { aptos } = getAptosClient(config); const emojicoinClient = new EmojicoinClient({ aptos }); - expect(aptos.config.clientConfig?.API_KEY).toEqual(APTOS_API_KEY); + expect(aptos.config.clientConfig?.API_KEY ?? "").toEqual(APTOS_API_KEY); expect(emojicoinClient.aptos.config.clientConfig?.API_KEY).toEqual(APTOS_API_KEY); }); From a97434133881b8d1245cc34f59eb91afe58cf8ea Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:12:23 -0800 Subject: [PATCH 08/14] Update test case --- src/typescript/sdk/tests/e2e/queries/client/submit.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts b/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts index 96445d79c..4d1d13939 100644 --- a/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts +++ b/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts @@ -111,7 +111,7 @@ describe("all submission types for the emojicoin client", () => { }); const aptos = new Aptos(config); const emojicoinClient = new EmojicoinClient({ aptos }); - expect(aptos.config.clientConfig?.API_KEY ?? "").toEqual(APTOS_API_KEY); + expect(aptos.config.clientConfig?.API_KEY).toEqual(undefined); expect(emojicoinClient.aptos.config.clientConfig?.API_KEY).toEqual(APTOS_API_KEY); }); @@ -121,7 +121,7 @@ describe("all submission types for the emojicoin client", () => { }); const { aptos } = getAptosClient(config); const emojicoinClient = new EmojicoinClient({ aptos }); - expect(aptos.config.clientConfig?.API_KEY ?? "").toEqual(APTOS_API_KEY); + expect(aptos.config.clientConfig?.API_KEY).toEqual(APTOS_API_KEY); expect(emojicoinClient.aptos.config.clientConfig?.API_KEY).toEqual(APTOS_API_KEY); }); From c9af3aefd797a32fb5b07ff4b0e80bd5ae0e2f5b Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:24:41 -0800 Subject: [PATCH 09/14] Warn if using `custom` and network isn't set, otherwise ignore --- src/docker/frontend/Dockerfile | 2 +- src/typescript/sdk/src/const.ts | 13 ++++++++++--- .../sdk/tests/e2e/queries/client/submit.test.ts | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/docker/frontend/Dockerfile b/src/docker/frontend/Dockerfile index 7a3dddef9..f1f03d67c 100644 --- a/src/docker/frontend/Dockerfile +++ b/src/docker/frontend/Dockerfile @@ -41,6 +41,6 @@ ENV HASH_SEED=$HASH_SEED \ NEXT_PUBLIC_TESTNET_APTOS_API_KEY=$FRONTEND_TESTNET_APTOS_API_KEY \ NEXT_PUBLIC_MAINNET_APTOS_API_KEY=$FRONTEND_MAINNET_APTOS_API_KEY -RUN ["bash", "-c", "pnpm install && pnpm run build:no-checks"] +RUN ["bash", "-c", "pnpm install && pnpm run build:test"] CMD ["bash", "-c", "pnpm run start -- -H 0.0.0.0"] diff --git a/src/typescript/sdk/src/const.ts b/src/typescript/sdk/src/const.ts index d3df6e94a..e3e73130b 100644 --- a/src/typescript/sdk/src/const.ts +++ b/src/typescript/sdk/src/const.ts @@ -41,15 +41,22 @@ if (!APTOS_NETWORK) { } const allAPIKeys: Record = { - [Network.LOCAL]: process.env.NEXT_PUBLIC_LOCAL_APTOS_API_KEY ?? "", - [Network.CUSTOM]: process.env.NEXT_PUBLIC_CUSTOM_APTOS_API_KEY ?? "", + [Network.LOCAL]: process.env.NEXT_PUBLIC_LOCAL_APTOS_API_KEY, + [Network.CUSTOM]: process.env.NEXT_PUBLIC_CUSTOM_APTOS_API_KEY, [Network.DEVNET]: process.env.NEXT_PUBLIC_DEVNET_APTOS_API_KEY, [Network.TESTNET]: process.env.NEXT_PUBLIC_TESTNET_APTOS_API_KEY, [Network.MAINNET]: process.env.NEXT_PUBLIC_MAINNET_APTOS_API_KEY, }; + const apiKey = allAPIKeys[APTOS_NETWORK]; if (typeof apiKey === "undefined") { - throw new Error(`Invalid API key set for the network: ${APTOS_NETWORK}: ${apiKey}`); + // Do nothing if we're on a local network, because we don't need an API key for it. For custom, + // warn the developer. + if (APTOS_NETWORK === "custom") { + console.warn(`No API key set. Ignoring because we're on the \`${APTOS_NETWORK}\` network.`); + } else { + throw new Error(`Invalid API key set for the network: ${APTOS_NETWORK}: ${apiKey}`); + } } // Select the API key from the list of env API keys. This means we don't have to change the env // var for API keys when changing environments- we just need to provide them all every time, which diff --git a/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts b/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts index 4d1d13939..a73fa918f 100644 --- a/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts +++ b/src/typescript/sdk/tests/e2e/queries/client/submit.test.ts @@ -111,7 +111,7 @@ describe("all submission types for the emojicoin client", () => { }); const aptos = new Aptos(config); const emojicoinClient = new EmojicoinClient({ aptos }); - expect(aptos.config.clientConfig?.API_KEY).toEqual(undefined); + expect(aptos.config.clientConfig?.API_KEY).toEqual(APTOS_API_KEY); expect(emojicoinClient.aptos.config.clientConfig?.API_KEY).toEqual(APTOS_API_KEY); }); From 2e6dbea70c3bf6a48035272384479cad745e88e3 Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:26:17 -0800 Subject: [PATCH 10/14] Fix logic for warning --- .../frontend/src/app/verify_api_keys/page.tsx | 2 +- src/typescript/sdk/src/const.ts | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/typescript/frontend/src/app/verify_api_keys/page.tsx b/src/typescript/frontend/src/app/verify_api_keys/page.tsx index 57a4985b5..81a40bb2e 100644 --- a/src/typescript/frontend/src/app/verify_api_keys/page.tsx +++ b/src/typescript/frontend/src/app/verify_api_keys/page.tsx @@ -4,7 +4,7 @@ import { getAptosClient } from "@sdk/utils/aptos-client"; export const dynamic = "force-static"; export const revalidate = 600; -export const runtime = 'nodejs'; +export const runtime = "nodejs"; const VerifyApiKeys = async () => { const { aptos } = getAptosClient(); diff --git a/src/typescript/sdk/src/const.ts b/src/typescript/sdk/src/const.ts index e3e73130b..0c03b1f9e 100644 --- a/src/typescript/sdk/src/const.ts +++ b/src/typescript/sdk/src/const.ts @@ -50,12 +50,13 @@ const allAPIKeys: Record = { const apiKey = allAPIKeys[APTOS_NETWORK]; if (typeof apiKey === "undefined") { - // Do nothing if we're on a local network, because we don't need an API key for it. For custom, - // warn the developer. - if (APTOS_NETWORK === "custom") { - console.warn(`No API key set. Ignoring because we're on the \`${APTOS_NETWORK}\` network.`); - } else { - throw new Error(`Invalid API key set for the network: ${APTOS_NETWORK}: ${apiKey}`); + // Do nothing if we're on a local network, because we don't need an API key for it. + if (APTOS_NETWORK !== "local") { + if (APTOS_NETWORK === "custom") { + console.warn(`No API key set. Ignoring because we're on the \`${APTOS_NETWORK}\` network.`); + } else { + throw new Error(`Invalid API key set for the network: ${APTOS_NETWORK}: ${apiKey}`); + } } } // Select the API key from the list of env API keys. This means we don't have to change the env From 7cd9526372b5a8cc07d67aa2ab31f72827b45a93 Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:41:26 -0800 Subject: [PATCH 11/14] Add inline cspell disable for API keys --- src/docker/example.local.env | 6 +++--- src/docker/example.testnet.env | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/docker/example.local.env b/src/docker/example.local.env index ebe7d7bb8..89f9d9877 100644 --- a/src/docker/example.local.env +++ b/src/docker/example.local.env @@ -81,6 +81,6 @@ HASH_SEED="some random string that is not public" # Set the API keys for the various frontend networks. It is okay if these are exposed publicly. FRONTEND_LOCAL_APTOS_API_KEY="" FRONTEND_CUSTOM_APTOS_API_KEY="" -FRONTEND_DEVNET_APTOS_API_KEY="AG-MSPVZN9BNPNB6KWSPZN7GHSETJU2TFLHJ" -FRONTEND_TESTNET_APTOS_API_KEY="AG-FRGKQEVCNY5PDJKZBAVTVCPGEQ6YFUBBX" -FRONTEND_MAINNET_APTOS_API_KEY="AG-BAGXRD2QME5WFTBZVAR4BPA7M5EGTBRHQ" +FRONTEND_DEVNET_APTOS_API_KEY="AG-MSPVZN9BNPNB6KWSPZN7GHSETJU2TFLHJ" # cspell:next-line +FRONTEND_TESTNET_APTOS_API_KEY="AG-FRGKQEVCNY5PDJKZBAVTVCPGEQ6YFUBBX" # cspell:next-line +FRONTEND_MAINNET_APTOS_API_KEY="AG-BAGXRD2QME5WFTBZVAR4BPA7M5EGTBRHQ" # cspell:next-line diff --git a/src/docker/example.testnet.env b/src/docker/example.testnet.env index 144406d9d..6925e1b28 100644 --- a/src/docker/example.testnet.env +++ b/src/docker/example.testnet.env @@ -68,6 +68,6 @@ HASH_SEED="some random string that is not public" # Set the API keys for the various frontend networks. It is okay if these are exposed publicly. FRONTEND_LOCAL_APTOS_API_KEY="" FRONTEND_CUSTOM_APTOS_API_KEY="" -FRONTEND_DEVNET_APTOS_API_KEY="AG-MSPVZN9BNPNB6KWSPZN7GHSETJU2TFLHJ" -FRONTEND_TESTNET_APTOS_API_KEY="AG-FRGKQEVCNY5PDJKZBAVTVCPGEQ6YFUBBX" -FRONTEND_MAINNET_APTOS_API_KEY="AG-BAGXRD2QME5WFTBZVAR4BPA7M5EGTBRHQ" +FRONTEND_DEVNET_APTOS_API_KEY="AG-MSPVZN9BNPNB6KWSPZN7GHSETJU2TFLHJ" # cspell:next-line +FRONTEND_TESTNET_APTOS_API_KEY="AG-FRGKQEVCNY5PDJKZBAVTVCPGEQ6YFUBBX" # cspell:next-line +FRONTEND_MAINNET_APTOS_API_KEY="AG-BAGXRD2QME5WFTBZVAR4BPA7M5EGTBRHQ" # cspell:next-line From 3f5c251dbe587b8b59dcc3a54bf9510cb71723ee Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:42:33 -0800 Subject: [PATCH 12/14] Disable cspell per line correctly --- src/docker/example.local.env | 6 +++--- src/docker/example.testnet.env | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/docker/example.local.env b/src/docker/example.local.env index 89f9d9877..4fe34dba4 100644 --- a/src/docker/example.local.env +++ b/src/docker/example.local.env @@ -81,6 +81,6 @@ HASH_SEED="some random string that is not public" # Set the API keys for the various frontend networks. It is okay if these are exposed publicly. FRONTEND_LOCAL_APTOS_API_KEY="" FRONTEND_CUSTOM_APTOS_API_KEY="" -FRONTEND_DEVNET_APTOS_API_KEY="AG-MSPVZN9BNPNB6KWSPZN7GHSETJU2TFLHJ" # cspell:next-line -FRONTEND_TESTNET_APTOS_API_KEY="AG-FRGKQEVCNY5PDJKZBAVTVCPGEQ6YFUBBX" # cspell:next-line -FRONTEND_MAINNET_APTOS_API_KEY="AG-BAGXRD2QME5WFTBZVAR4BPA7M5EGTBRHQ" # cspell:next-line +FRONTEND_DEVNET_APTOS_API_KEY="AG-MSPVZN9BNPNB6KWSPZN7GHSETJU2TFLHJ" # cspell:disable-line +FRONTEND_TESTNET_APTOS_API_KEY="AG-FRGKQEVCNY5PDJKZBAVTVCPGEQ6YFUBBX" # cspell:disable-line +FRONTEND_MAINNET_APTOS_API_KEY="AG-BAGXRD2QME5WFTBZVAR4BPA7M5EGTBRHQ" # cspell:disable-line diff --git a/src/docker/example.testnet.env b/src/docker/example.testnet.env index 6925e1b28..ea38fe114 100644 --- a/src/docker/example.testnet.env +++ b/src/docker/example.testnet.env @@ -68,6 +68,6 @@ HASH_SEED="some random string that is not public" # Set the API keys for the various frontend networks. It is okay if these are exposed publicly. FRONTEND_LOCAL_APTOS_API_KEY="" FRONTEND_CUSTOM_APTOS_API_KEY="" -FRONTEND_DEVNET_APTOS_API_KEY="AG-MSPVZN9BNPNB6KWSPZN7GHSETJU2TFLHJ" # cspell:next-line -FRONTEND_TESTNET_APTOS_API_KEY="AG-FRGKQEVCNY5PDJKZBAVTVCPGEQ6YFUBBX" # cspell:next-line -FRONTEND_MAINNET_APTOS_API_KEY="AG-BAGXRD2QME5WFTBZVAR4BPA7M5EGTBRHQ" # cspell:next-line +FRONTEND_DEVNET_APTOS_API_KEY="AG-MSPVZN9BNPNB6KWSPZN7GHSETJU2TFLHJ" # cspell:disable-line +FRONTEND_TESTNET_APTOS_API_KEY="AG-FRGKQEVCNY5PDJKZBAVTVCPGEQ6YFUBBX" # cspell:disable-line +FRONTEND_MAINNET_APTOS_API_KEY="AG-BAGXRD2QME5WFTBZVAR4BPA7M5EGTBRHQ" # cspell:disable-line From 5f8b16280104d6bf126847b9d3f4690952d0c4b4 Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Mon, 18 Nov 2024 18:05:40 -0800 Subject: [PATCH 13/14] Fix client config merge --- src/typescript/sdk/src/client/emojicoin-client.ts | 5 ++++- src/typescript/sdk/src/utils/aptos-client.ts | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/typescript/sdk/src/client/emojicoin-client.ts b/src/typescript/sdk/src/client/emojicoin-client.ts index f9f542fbd..7fe497214 100644 --- a/src/typescript/sdk/src/client/emojicoin-client.ts +++ b/src/typescript/sdk/src/client/emojicoin-client.ts @@ -147,7 +147,10 @@ export class EmojicoinClient { minOutputAmount = 1n, } = args ?? {}; // Create a client that always uses the static API_KEY config options. - const hardCodedConfig = new AptosConfig({ ...aptos.config, clientConfig: APTOS_CONFIG }); + const hardCodedConfig = new AptosConfig({ + ...aptos.config, + clientConfig: { ...aptos.config.clientConfig, ...APTOS_CONFIG }, + }); this.aptos = new Aptos(hardCodedConfig); this.integrator = AccountAddress.from(integrator); this.integratorFeeRateBPs = Number(integratorFeeRateBPs); diff --git a/src/typescript/sdk/src/utils/aptos-client.ts b/src/typescript/sdk/src/utils/aptos-client.ts index 27ffd317e..e493d89af 100644 --- a/src/typescript/sdk/src/utils/aptos-client.ts +++ b/src/typescript/sdk/src/utils/aptos-client.ts @@ -13,7 +13,10 @@ export function getAptosClient(additionalConfig?: Partial): { const config = new AptosConfig({ network, ...additionalConfig, - ...APTOS_CONFIG, + clientConfig: { + ...additionalConfig?.clientConfig, + ...APTOS_CONFIG, + }, }); const aptos = new Aptos(config); return { aptos, config }; From b7c8ab57a0bebdcf62eba3c962a81efb6a361539 Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Mon, 18 Nov 2024 18:08:38 -0800 Subject: [PATCH 14/14] Make error message more explicit for invalid API key --- src/typescript/frontend/src/app/verify_api_keys/page.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/typescript/frontend/src/app/verify_api_keys/page.tsx b/src/typescript/frontend/src/app/verify_api_keys/page.tsx index 81a40bb2e..040d57afb 100644 --- a/src/typescript/frontend/src/app/verify_api_keys/page.tsx +++ b/src/typescript/frontend/src/app/verify_api_keys/page.tsx @@ -13,7 +13,8 @@ const VerifyApiKeys = async () => { try { balance = await aptos.account.getAccountAPTAmount({ accountAddress }); } catch (e) { - throw new Error(`Couldn't fetch ${accountAddress}'s balance. APTOS_API_KEY: ${APTOS_API_KEY}`); + const msg = `\n\tLikely an invalid API key. APTOS_API_KEY: ${APTOS_API_KEY}`; + throw new Error(`Couldn't fetch ${accountAddress}'s balance. ${msg}`); } return (