From 44ff4f131163c59972bf06a6f49d3bf3621da301 Mon Sep 17 00:00:00 2001 From: Stanley Yuen <102275989+stanleyyconsensys@users.noreply.github.com> Date: Fri, 5 Apr 2024 08:50:04 +0800 Subject: [PATCH] fix: sf 606 fix voyager cors with official provider (#229) * fix: voyager cors issue * chore: update voyager endpoint * chore: update cicd * chore: rollback file * chore: update switch case --- .github/workflows/deploy.yml | 4 +- .github/workflows/publish-npm-dev.yml | 2 +- packages/starknet-snap/snap.config.js | 1 + packages/starknet-snap/src/utils/snapUtils.ts | 23 +++++++-- .../starknet-snap/src/utils/starknetUtils.ts | 18 +++++-- .../test/utils/snapUtils.test.ts | 48 ++++++++++++++++++- 6 files changed, 84 insertions(+), 12 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ac669a8a..faeb1e84 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -48,7 +48,7 @@ jobs: REACT_APP_SNAP_VERSION=${VERSION}-staging yarn workspace wallet-ui build npm --prefix ./packages/starknet-snap version --new-version ${VERSION}-staging --no-git-tag-version - SNAP_ENV=staging yarn workspace @consensys/starknet-snap build + SNAP_ENV=staging VOYAGER_API_KEY=${{ secrets.VOYAGER_API_KEY }} yarn workspace @consensys/starknet-snap build npm publish ./packages/starknet-snap --tag staging --access public 2>&1 > /dev/null || : aws s3 sync ./packages/wallet-ui/build s3://staging.snaps.consensys.io/starknet @@ -62,7 +62,7 @@ jobs: REACT_APP_SNAP_VERSION=${VERSION} REACT_APP_DEBUG_LEVEL=off yarn workspace wallet-ui build npm --prefix ./packages/starknet-snap version --new-version ${VERSION} --no-git-tag-version --allow-same-version - SNAP_ENV=prod yarn workspace @consensys/starknet-snap build + SNAP_ENV=prod VOYAGER_API_KEY=${{ secrets.VOYAGER_API_KEY }} yarn workspace @consensys/starknet-snap build npm publish ./packages/starknet-snap --tag latest --access public 2>&1 > /dev/null || : aws s3 sync ./packages/wallet-ui/build s3://snaps.consensys.io/starknet diff --git a/.github/workflows/publish-npm-dev.yml b/.github/workflows/publish-npm-dev.yml index 7ef833e0..22a72129 100644 --- a/.github/workflows/publish-npm-dev.yml +++ b/.github/workflows/publish-npm-dev.yml @@ -24,7 +24,7 @@ jobs: HASH=$(git rev-parse --short HEAD) DATE=$(date +%Y%m%d) npm --prefix ./packages/starknet-snap version --new-version ${VERSION}-dev-${HASH}-${DATE} --no-git-tag-version - SNAP_ENV=dev yarn workspace @consensys/starknet-snap build + SNAP_ENV=dev VOYAGER_API_KEY=${{ secrets.VOYAGER_API_KEY }} yarn workspace @consensys/starknet-snap build - uses: actions/setup-node@v3 with: diff --git a/packages/starknet-snap/snap.config.js b/packages/starknet-snap/snap.config.js index 1e6bb254..51212828 100644 --- a/packages/starknet-snap/snap.config.js +++ b/packages/starknet-snap/snap.config.js @@ -10,6 +10,7 @@ module.exports = { bundler.transform( envify({ SNAP_ENV: process.env.SNAP_ENV, + VOYAGER_API_KEY: process.env.VOYAGER_API_KEY, }), ); }, diff --git a/packages/starknet-snap/src/utils/snapUtils.ts b/packages/starknet-snap/src/utils/snapUtils.ts index 2a6d4ac3..9294c5ea 100644 --- a/packages/starknet-snap/src/utils/snapUtils.ts +++ b/packages/starknet-snap/src/utils/snapUtils.ts @@ -8,6 +8,7 @@ import { DeclareSignerDetails, Call, DeployAccountSignerDetails, + constants, } from 'starknet'; import { validateAndParseAddress } from './starknetUtils'; import { Component, text, copyable } from '@metamask/snaps-sdk'; @@ -28,8 +29,6 @@ import { PRELOADED_NETWORKS, PRELOADED_TOKENS, STARKNET_SEPOLIA_TESTNET_NETWORK, - VOYAGER_API_TXNS_URL_SUFFIX, - VOYAGER_API_TXN_URL_SUFFIX, } from './constants'; import convert from 'ethereum-unit-converter'; import { AddErc20TokenRequestParams, AddNetworkRequestParams } from '../types/snapApi'; @@ -527,12 +526,28 @@ export function getChainIdHex(network: Network) { return `0x${num.toBigInt(network.chainId).toString(16)}`; } +export function getVoyagerUrl(chainId: string) { + switch (chainId) { + case STARKNET_SEPOLIA_TESTNET_NETWORK.chainId: + return `https://sepolia-api.voyager.online/beta`; + case constants.StarknetChainId.SN_MAIN: + default: + return `https://api.voyager.online/beta`; + } +} + +export function getVoyagerCredentials(): Record { + return { + 'X-API-Key': process.env.VOYAGER_API_KEY, + }; +} + export function getTransactionFromVoyagerUrl(network: Network) { - return `${network.voyagerUrl}${VOYAGER_API_TXN_URL_SUFFIX}`; + return `${getVoyagerUrl(network.chainId)}/txn`; } export function getTransactionsFromVoyagerUrl(network: Network) { - return `${network.voyagerUrl}${VOYAGER_API_TXNS_URL_SUFFIX}`; + return `${getVoyagerUrl(network.chainId)}/txns`; } export function getTransaction(state: SnapState, txnHash: string, chainId: string) { diff --git a/packages/starknet-snap/src/utils/starknetUtils.ts b/packages/starknet-snap/src/utils/starknetUtils.ts index 7e52561b..4cf9698f 100644 --- a/packages/starknet-snap/src/utils/starknetUtils.ts +++ b/packages/starknet-snap/src/utils/starknetUtils.ts @@ -37,7 +37,13 @@ import type { Hex } from '@noble/curves/abstract/utils'; import { Network, SnapState, Transaction, TransactionType } from '../types/snapState'; import { ACCOUNT_CLASS_HASH_V0, PROXY_CONTRACT_HASH, TRANSFER_SELECTOR_HEX } from './constants'; import { getAddressKey } from './keyPair'; -import { getAccount, getAccounts, getTransactionFromVoyagerUrl, getTransactionsFromVoyagerUrl } from './snapUtils'; +import { + getAccount, + getAccounts, + getTransactionFromVoyagerUrl, + getTransactionsFromVoyagerUrl, + getVoyagerCredentials, +} from './snapUtils'; import { logger } from './logger'; import { RpcV4GetTransactionReceiptResponse } from '../types/snapApi'; @@ -201,12 +207,15 @@ export const getTransactionsFromVoyager = async ( toQueryStr = `to=${num.toHex(num.toBigInt(toAddress))}&`; } // "ps" only effective on value: 10, 25, 50 as what's currently available in Voyager page - return getData(`${getTransactionsFromVoyagerUrl(network)}?${toQueryStr}ps=${pageSize}&p=${pageNum}`); + return getData( + `${getTransactionsFromVoyagerUrl(network)}?${toQueryStr}ps=${pageSize}&p=${pageNum}`, + getVoyagerCredentials(), + ); }; export const getTransactionFromVoyager = async (transactionHash: num.BigNumberish, network: Network) => { const txHashHex = num.toHex(num.toBigInt(transactionHash)); - return getData(`${getTransactionFromVoyagerUrl(network)}/${txHashHex}`); + return getData(`${getTransactionFromVoyagerUrl(network)}/${txHashHex}`, getVoyagerCredentials()); }; const getTransactionsFromVoyagerHelper = async ( @@ -335,11 +344,12 @@ export const getMassagedTransactions = async ( return massagedTxns; }; -export const getData = async (url = '') => { +export const getData = async (url = '', headers: Record = {}) => { // Default options are marked with * const response = await fetch(url, { method: 'GET', // *GET, POST, PUT, DELETE, etc. redirect: 'follow', // manual, *follow, error + headers: headers, }); return response.json(); // parses JSON response into native JavaScript objects }; diff --git a/packages/starknet-snap/test/utils/snapUtils.test.ts b/packages/starknet-snap/test/utils/snapUtils.test.ts index b631b306..c0c6a5c6 100644 --- a/packages/starknet-snap/test/utils/snapUtils.test.ts +++ b/packages/starknet-snap/test/utils/snapUtils.test.ts @@ -1,7 +1,14 @@ import { expect } from 'chai'; import { Mutex } from 'async-mutex'; -import { dappUrl, removeNetwork } from '../../src/utils/snapUtils'; +import { + dappUrl, + removeNetwork, + getVoyagerUrl, + getTransactionFromVoyagerUrl, + getTransactionsFromVoyagerUrl, + getVoyagerCredentials, +} from '../../src/utils/snapUtils'; import { WalletMock } from '../wallet.mock.test'; import { Network, SnapState } from '../../src/types/snapState'; import { @@ -9,6 +16,7 @@ import { STARKNET_TESTNET_NETWORK, STARKNET_MAINNET_NETWORK, } from '../../src/utils/constants'; +import { constants } from 'starknet'; describe('Snap Utils', () => { it('should return the proper dapp URL based on the environment', () => { @@ -87,3 +95,41 @@ describe('removeNetwork', () => { expect(state.currentNetwork).to.be.eql(STARKNET_MAINNET_NETWORK); }); }); + +describe('getVoyagerUrl', () => { + it('returns Mainnet URL if chain id is Mainnet', () => { + expect(getVoyagerUrl(constants.StarknetChainId.SN_MAIN)).to.be.equal('https://api.voyager.online/beta'); + }); + + it('returns Mainnet URL if chain id is not either Mainnet or Sepolia', () => { + expect(getVoyagerUrl('0x534e5f474f45524c49')).to.be.equal('https://api.voyager.online/beta'); + }); + + it('returns Sepolia URL if chain id is Sepolia', () => { + expect(getVoyagerUrl(STARKNET_SEPOLIA_TESTNET_NETWORK.chainId)).to.be.equal( + 'https://sepolia-api.voyager.online/beta', + ); + }); +}); + +describe('getTransactionFromVoyagerUrl', () => { + it('returns correct URL', () => { + expect(getTransactionFromVoyagerUrl({ chainId: constants.StarknetChainId.SN_MAIN } as Network)).to.be.equal( + 'https://api.voyager.online/beta/txn', + ); + }); +}); + +describe('getTransactionsFromVoyagerUrl', () => { + it('returns correct URL', () => { + expect(getTransactionsFromVoyagerUrl({ chainId: constants.StarknetChainId.SN_MAIN } as Network)).to.be.equal( + 'https://api.voyager.online/beta/txns', + ); + }); +}); + +describe('getVoyagerCredentials', () => { + it('returns correct credentials', () => { + expect(getVoyagerCredentials()).to.have.key('X-API-Key'); + }); +});