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

[BLCKCHN-203] CronosId TS client Integration #9

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
7,150 changes: 1,957 additions & 5,193 deletions package-lock.json

Large diffs are not rendered by default.

26 changes: 23 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Block } from './lib/client/Block.js';
import { Client } from './lib/client/Client.js';
import { Contract } from './lib/client/Contract.js';
import { CronosId } from './lib/client/Cronosid.js';
import { Defi } from './lib/client/Defi.js';
import { Exchange } from './lib/client/Exchange.js';
import { CronosEvm, CronosZkEvm } from './lib/client/interfaces/chain.interfaces.js';
import { DefiProtocol } from './lib/client/interfaces/defi.interfaces.js';
import { Token } from './lib/client/Token.js';
import { Transaction } from './lib/client/Transaction.js';
import { Wallet } from './lib/client/Wallet.js';
import { CronosEvm, CronosZkEvm } from './lib/client/interfaces/chain.interfaces.js';
import { DefiProtocol } from './lib/client/interfaces/defi.interfaces.js';

/**
* Client class for configuring and managing SDK functionality.
Expand Down Expand Up @@ -71,4 +72,23 @@ import { DefiProtocol } from './lib/client/interfaces/defi.interfaces.js';
* @module Defi
*/

export { Block, Client, Contract, CronosEvm, CronosZkEvm, Defi, DefiProtocol, Exchange, Token, Transaction, Wallet };
/**
* CronosId class for fetching CronosId information.
*
* @module CronosId
*/

export {
Block,
Client,
Contract,
CronosEvm,
CronosId,
CronosZkEvm,
Defi,
DefiProtocol,
Exchange,
Token,
Transaction,
Wallet,
};
2 changes: 1 addition & 1 deletion src/integrations/block.api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { GetBlockByTag } from '../lib/client/interfaces/block.interfaces.js';
import { BASE_URL } from '../lib/constants/global.constants.js';
import { ApiResponse, Method } from './api.interfaces.js';
import { BASE_URL } from './const.js';
/**
* Fetches a block by tag or block number.
*
Expand Down
2 changes: 1 addition & 1 deletion src/integrations/contract.api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { GetContractAbiData } from '../lib/client/interfaces/contract.interfaces.js';
import { BASE_URL } from '../lib/constants/global.constants.js';
import { ApiResponse, Method } from './api.interfaces.js';
import { BASE_URL } from './const.js';

/**
* Fetches the ABI (Application Binary Interface) of a specific contract by its address on a particular blockchain network.
Expand Down
80 changes: 80 additions & 0 deletions src/integrations/cronosid.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Client } from '../lib/client/Client.js';
import { LookupAddressResponse, ResolveNameResponse } from '../lib/client/interfaces/cronosid.interfaces.js';
import { BASE_URL } from '../lib/constants/global.constants.js';
import { ApiResponse } from './api.interfaces.js';

/**
* Resolves a CronosId to its corresponding blockchain address
*
* @async
* @function resolveName
* @param {string} name - The CronosId name to resolve
* @returns {Promise<string>} - A promise that resolves to the blockchain address
* @throws {Error} Will throw an error if the fetch request fails or the server responds with an error message
*
* @example
* const address = await resolveName('example.cro');
* console.log(address); // '0x...'
*/
export const resolveName = async (name: string): Promise<ApiResponse<ResolveNameResponse>> => {
const chainId = Client.getChainId();
const url = `${BASE_URL}/api/v1/cdc-developer-platform/cronosid/resolve/${name}?chainId=${chainId}`;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about using encodeURIComponent for name, chainId?


try {
const response = await fetch(url, {
headers: {
'Content-Type': 'application/json',
},
});

if (!response.ok) {
const errorBody = await response.json();
Copy link
Collaborator

@leejw51crypto leejw51crypto Dec 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about adding validation whether response is json

const serverErrorMessage = errorBody.error || `HTTP error! status: ${response.status}`;
throw new Error(serverErrorMessage);
}

return await response.json();
} catch (e) {
const error = e as Error;
console.error(`[cronosidApi/resolveName] - ${error.message}`);
throw new Error(`Failed to resolve name: ${error.message}`);
}
};

/**
* Looks up an address to find its associated CronosId
*
* @async
* @function lookupAddress
* @param {string} address - The blockchain address to lookup
* @returns {Promise<string>} - A promise that resolves to the CronosId name
* @throws {Error} Will throw an error if the fetch request fails or the server responds with an error message
*
* @example
* const name = await lookupAddress('0x...');
* console.log(name); // 'example.cro'
*/
export const lookupAddress = async (address: string): Promise<ApiResponse<LookupAddressResponse>> => {
const chainId = Client.getChainId();
const url = `${BASE_URL}/api/v1/cdc-developer-platform/cronosid/lookup/${address}?chainId=${chainId}`;

try {
const response = await fetch(url, {
headers: {
'Content-Type': 'application/json',
},
});

if (!response.ok) {
const errorBody = await response.json();
const serverErrorMessage = errorBody.error || `HTTP error! status: ${response.status}`;
throw new Error(serverErrorMessage);
}

return await response.json();
} catch (e) {
const error = e as Error;
console.error(`[cronosidApi/lookupAddress] - ${error.message}`);
throw new Error(`Failed to lookup address: ${error.message}`);
}
};
2 changes: 1 addition & 1 deletion src/integrations/defi.api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DefiProtocol, Farm, WhitelistedToken } from '../lib/client/interfaces/defi.interfaces.js';
import { BASE_URL } from '../lib/constants/global.constants.js';
import { ApiResponse, Method } from './api.interfaces.js';
import { BASE_URL } from './const.js';

/**
* Fetches whitelisted tokens for a specific DeFi protocol.
Expand Down
2 changes: 1 addition & 1 deletion src/integrations/exchange.api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TickerData } from '../lib/client/interfaces/exchange.interfaces.js';
import { BASE_URL } from '../lib/constants/global.constants.js';
import { ApiResponse, Method } from './api.interfaces.js';
import { BASE_URL } from './const.js';

/**
* Fetches all tickers from the exchange.
Expand Down
8 changes: 4 additions & 4 deletions src/integrations/token.api.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { TokenBalance } from '../lib/client/interfaces/explorer.interfaces.js';
import { Balance } from '../lib/client/interfaces/token.interfaces.js';
import { MagicLinkData } from '../lib/client/interfaces/transaction.interfaces.js';
import { BASE_URL } from '../lib/constants/global.constants.js';
import { ApiResponse, Method } from './api.interfaces.js';
import { BASE_URL } from './const.js';

/**
* Fetches the native token balance of a specific address on a blockchain.
*
* @async
* @function getNativeTokenBalance
* @param {string} chainId - The ID of the blockchain network (e.g., Ethereum, Cronos).
* @param {string} address - The wallet address to fetch the native token balance for.
* @param {string} address - The wallet address to fetch the native token balance for (CronosIds with the `.cro` suffix are supported, e.g. `XXX.cro`)
* @param {string} apiKey - The API key used for authentication with the server.
* @returns {Promise<ApiResponse<Balance>>} - A promise that resolves to the balance of the native token.
* @throws {Error} Will throw an error if the fetch request fails or the server responds with an error message.
Expand Down Expand Up @@ -54,7 +54,7 @@ export const getNativeTokenBalance = async (
* @async
* @function getERC20TokenBalance
* @param {string} chainId - The ID of the blockchain network (e.g., Ethereum, Cronos).
* @param {string} address - The wallet address to fetch the ERC20 token balance for.
* @param {string} address - The wallet address to fetch the ERC20 token balance for (CronosIds with the `.cro` suffix are supported, e.g. `XXX.cro`)
* @param {string} contractAddress - The contract address of the ERC20 token.
* @param {string} [blockHeight='latest'] - Optional. The block height to query (default is 'latest').
* @param {string} apiKey - The API key used for authentication with the server.
Expand Down Expand Up @@ -102,7 +102,7 @@ export const getERC20TokenBalance = async (
* @async
* @function transferToken
* @param {string} chainId - The ID of the blockchain network.
* @param {object} payload - The transaction payload including 'to' address, 'amount', and optional 'contractAddress'.
* @param {object} payload - The transaction payload including 'to' address (CronosIds with the `.cro` suffix are supported, e.g. `XXX.cro`), 'amount', and optional 'contractAddress'.
* @param {string} [provider] - Optional. The provider URL for the blockchain network.
* @returns {Promise<ApiResponse<MagicLinkData>>} - A promise that resolves to the result of the transaction.
* @throws {Error} Will throw an error if the transaction fails or the server responds with an error message.
Expand Down
4 changes: 2 additions & 2 deletions src/integrations/transaction.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import {
GetTransactionsByAddressData,
GetTransactionStatusData,
} from '../lib/client/interfaces/transaction.interfaces.js';
import { BASE_URL } from '../lib/constants/global.constants.js';
import { ApiResponse, Method } from './api.interfaces.js';
import { BASE_URL } from './const.js';

/**
* Fetches transactions for a specific wallet address.
*
* @async
* @param {string} chainId - The ID of the blockchain network (e.g., Ethereum, Cronos).
* @param {string} address - The wallet address to fetch transactions for (e.g., 0x...).
* @param {string} address - The wallet address to fetch transactions for (CronosIds with the `.cro` suffix are supported, e.g. `XXX.cro`)
* @param {string} [session] - Optional. The pagination session token.
* @param {string} [limit='20'] - Optional. The number of transactions to fetch.
* @param {string} apiKey - The API key for authentication.
Expand Down
4 changes: 2 additions & 2 deletions src/integrations/wallet.api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Balance } from '../lib/client/interfaces/token.interfaces.js';
import { CreateWalletData } from '../lib/client/interfaces/wallet.interfaces.js';
import { BASE_URL } from '../lib/constants/global.constants.js';
import { ApiResponse, Method } from './api.interfaces.js';
import { BASE_URL } from './const.js';

/**
* Creates a new wallet using the API.
Expand Down Expand Up @@ -45,7 +45,7 @@ export const createWallet = async (): Promise<ApiResponse<CreateWalletData>> =>
*
* @async
* @param {string} chainId - The ID of the blockchain network (e.g., Ethereum, Cronos).
* @param {string} address - The wallet address to check the balance for (e.g., 0x...).
* @param {string} address - The wallet address to check the balance for (CronosIds with the `.cro` suffix are supported, e.g. `XXX.cro`)
* @param {string} apiKey - The API key for authentication.
* @returns {Promise<ApiResponse<Balance>>} - The native token balance of the wallet.
* @throws {Error} Will throw an error if the fetch request fails or the server responds with an error message.
Expand Down
67 changes: 67 additions & 0 deletions src/lib/client/Cronosid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { ApiResponse } from '../../integrations/api.interfaces.js';
import { lookupAddress, resolveName } from '../../integrations/cronosid.api.js';
import { ChainName } from '../utils/chain.utils.js';
import { Client } from './Client.js';
import { LookupAddressResponse, ResolveNameResponse } from './interfaces/cronosid.interfaces.js';

export class CronosId {
/**
* The registry contracts for CronosId on different chains - CronosId is supported on EVM and EVM Testnet only
*/
private static readonly supportedChains = [ChainName.CRONOS_EVM, ChainName.CRONOS_EVM_TESTNET];

/**
* Checks if a given string is a valid CronosId, which is a string ending with '.cro' and not empty.
* example: 'alice.cro' is a valid CronosId, but 'alice' is not.
*
* @param {string} name - The string to check for CronosId validity.
* @returns {boolean} - True if the string is a valid CronosId, false otherwise.
*/
public static isCronosId(name: string): boolean {
const lowercaseName = name.toLowerCase();
const parts = lowercaseName.split('.cro');
return lowercaseName.endsWith('.cro') && parts[0].length > 0;
}

/**
* Checks if CronosId is supported on the current chain specified in the client.
*
* @returns {boolean} - True if CronosId is supported on the current chain, false otherwise.
*/
public static isSupported(): boolean {
const chainId = Client.getChainId();
return this.supportedChains.includes(chainId as ChainName);
}

/**
* Resolves a CronosId to a wallet address
*
* @param {string} cronosId - The CronosId to resolve.
* @returns {Promise<string>} - A promise that resolves to the resolved address.
* @throws {Error} - Throws an error if the CronosId is not valid or if the resolution fails.
*/
public static async forwardResolve(cronosId: string): Promise<ApiResponse<ResolveNameResponse>> {
if (!this.isSupported()) {
throw new Error('CronosId is not supported on the current chain');
}
if (!this.isCronosId(cronosId)) {
throw new Error(`Invalid CronosId format: ${cronosId}`);
}
return await resolveName(cronosId);
}

/**
* Resolves a wallet address to a CronosId if it has one
*
* @param {string} address - The wallet address to resolve.
* @returns {Promise<string>} - A promise that resolves to the resolved CronosId.
* @throws {Error} - Throws an error if the address is not valid or if the resolution fails.
*/
public static async reverseResolve(address: string): Promise<ApiResponse<LookupAddressResponse>> {
if (!this.isSupported()) {
throw new Error('CronosId is not supported on the current chain');
}

return await lookupAddress(address);
}
}
6 changes: 3 additions & 3 deletions src/lib/client/Token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class Token {
* Fetches the native token balance of a specific wallet address.
*
* @async
* @param {string} address - The wallet address to check the native token balance for.
* @param {string} address - The wallet address to check the native token balance for (CronosIds with the `.cro` suffix are supported, e.g. `XXX.cro`)
* @returns {Promise<ApiResponse<Balance>>} - A promise that resolves to the balance of the native token.
* @throws {Error} - Throws an error if the request fails.
*
Expand All @@ -40,7 +40,7 @@ export class Token {
* Fetches the ERC20 token balance of a specific wallet address for a given ERC20 contract.
*
* @async
* @param {string} address - The wallet address to check the ERC20 token balance for.
* @param {string} address - The wallet address to check the ERC20 token balance for (CronosIds with the `.cro` suffix are supported, e.g. `XXX.cro`)
* @param {string} contractAddress - The contract address of the ERC20 token.
* @param {string} [blockHeight='latest'] - Optional. The block height to query, default is 'latest'.
* @returns {Promise<ApiResponse<TokenBalance>>} - A promise that resolves to the balance of the ERC20 token.
Expand All @@ -65,7 +65,7 @@ export class Token {
*
* @async
* @param {object} payload - The transaction payload containing `to`, `amount`, and optionally `contractAddress`.
* @param {string} payload.to - The recipient address of the transfer.
* @param {string} payload.to - The recipient address of the transfer (CronosIds with the `.cro` suffix are supported, e.g. `XXX.cro`)
* @param {number} payload.amount - The amount of tokens to transfer.
* @param {string} [payload.contractAddress] - Optional. The contract address of the ERC20 token (if transferring ERC20 tokens).
* @returns {Promise<ApiResponse<MagicLinkData>>} - A promise that resolves to the result of the transaction.
Expand Down
2 changes: 1 addition & 1 deletion src/lib/client/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class Transaction {
* Fetches transactions for a specific wallet address.
*
* @async
* @param {string} address - The wallet address to fetch transactions for.
* @param {string} address - The wallet address to fetch transactions for (CronosIds with the `.cro` suffix are supported, e.g. `XXX.cro`)
* @param {string} [session] - Optional. Session token for pagination (default is an empty string).
* @param {string} [limit] - Optional. Limit for the number of transactions to fetch (default is 20).
* @returns {Promise<ApiResponse<GetTransactionsByAddressData>>} - A promise that resolves to the transaction data for the specified address.
Expand Down
2 changes: 1 addition & 1 deletion src/lib/client/Wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class Wallet {
* Retrieves the balance of the wallet for a specific address.
*
* @async
* @param {string} address - The wallet address to fetch the balance for.
* @param {string} address - The wallet address to fetch the balance for (CronosIds with the `.cro` suffix are supported, e.g. `XXX.cro`)
* @returns {Promise<ApiResponse<Balance>>} - A promise that resolves to the balance of the wallet.
* @throws {Error} - Throws an error if the request fails.
*
Expand Down
7 changes: 7 additions & 0 deletions src/lib/client/interfaces/cronosid.interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface ResolveNameResponse {
resolvedAddress: string;
}

export interface LookupAddressResponse {
resolvedName: string;
}
Loading