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..4fe34dba4 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" # 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 39df3c32c..ea38fe114 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" # 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/frontend/Dockerfile b/src/docker/frontend/Dockerfile index 908e99374..f1f03d67c 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,8 +34,13 @@ 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 - -RUN ["bash", "-c", "pnpm install && pnpm run build:no-checks"] + 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:test"] CMD ["bash", "-c", "pnpm run start -- -H 0.0.0.0"] 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/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..040d57afb --- /dev/null +++ b/src/typescript/frontend/src/app/verify_api_keys/page.tsx @@ -0,0 +1,25 @@ +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) { + 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 ( +
{`Balance: ${balance}`}
+ ); +}; + +export default VerifyApiKeys; 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..0e0d4efa9 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 { type Network } from "@aptos-labs/ts-sdk"; export type Links = { x: string; @@ -10,7 +10,15 @@ export type Links = { tos: string; }; -let APTOS_NETWORK: 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; @@ -22,17 +30,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/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/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/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/sdk/src/client/emojicoin-client.ts b/src/typescript/sdk/src/client/emojicoin-client.ts index 3f936abea..7fe497214 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,12 @@ 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.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 d936c75ac..0c03b1f9e 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,15 @@ 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_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_NETWORK", process.env.NEXT_PUBLIC_APTOS_NETWORK], ].filter(([_, value]) => !value); missing.forEach(([key, _]) => { console.error(`Missing environment variables ${key}`); @@ -26,6 +34,35 @@ 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.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") { + // 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 +// 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..e493d89af 100644 --- a/src/typescript/sdk/src/utils/aptos-client.ts +++ b/src/typescript/sdk/src/utils/aptos-client.ts @@ -1,22 +1,23 @@ -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, + clientConfig: { + ...additionalConfig?.clientConfig, + ...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..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,4 +1,6 @@ import { + APTOS_API_KEY, + APTOS_NETWORK, getEmojicoinMarketAddressAndTypeTags, INTEGRATOR_ADDRESS, INTEGRATOR_FEE_RATE_BPS, @@ -20,7 +22,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 } from "../../../../src/utils/aptos-client"; import { calculatePeriodBoundariesCrossed } from "../../../../src/utils/test"; jest.setTimeout(15000); @@ -103,9 +105,29 @@ 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()); + expect(emojicoin.aptos.config.network).toEqual(APTOS_NETWORK); }); it("registers a market", async () => { 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": [] },