diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 78faf63..5d09189 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -9,7 +9,7 @@ app.use(express.json()); const providers: Record = { stonfi_v2: new StonfiProvider(process.env.TON_URL || "https://toncenter.com"), - mayan: new MayanProvider(process.env.MAYAN_URL || "https://solana-rpc.publicnode.com"), + mayan: new MayanProvider(process.env.SOLANA_URL || "https://solana-rpc.publicnode.com"), }; app.get('/:providerId/quote', async (req, res) => { @@ -30,7 +30,7 @@ app.get('/:providerId/quote', async (req, res) => { referral_bps: parseInt(req.query.referral_bps as string), slippage_bps: parseInt(req.query.slippage_bps as string), }; - + const quote = await provider.get_quote(request); res.json(quote); } catch (error) { @@ -53,10 +53,11 @@ app.post('/:providerId/quote_data', async (req, res) => { const quote_request = req.body as Quote; try { - console.log("quote_request", quote_request); + const quote = await provider.get_quote_data(quote_request); res.json(quote); } catch (error) { + console.log("quote_request", quote_request); if (error instanceof Error) { res.status(500).json({ error: error.message }); } else { diff --git a/packages/swapper/package.json b/packages/swapper/package.json index e7e583e..59cb00c 100644 --- a/packages/swapper/package.json +++ b/packages/swapper/package.json @@ -17,7 +17,8 @@ "@solana/web3.js": "1.98.0", "@ston-fi/api": "0.21.0", "@ston-fi/sdk": "2.3.0", - "@ton/ton": "15.2.1" + "@ton/ton": "15.2.1", + "ethers": "6.13.5" }, "devDependencies": { "@types/jest": "29.5.14", @@ -28,4 +29,4 @@ "files": [ "dist" ] -} +} \ No newline at end of file diff --git a/packages/swapper/src/bigint.ts b/packages/swapper/src/bigint.ts new file mode 100644 index 0000000..611d55f --- /dev/null +++ b/packages/swapper/src/bigint.ts @@ -0,0 +1,21 @@ +import { parseUnits } from "ethers"; + +/** + * Converts a decimal string or number from one decimal precision to another + * @param value The decimal to convert + * @param toDecimals The target number of decimals + * @param fromDecimals The source number of decimals (default is 18) + * @returns A BigInt with the converted value + */ +export function parseDecimals(value: string | number, toDecimals: number, fromDecimals = 18): BigInt { + const parsedValue = parseUnits(value.toString(), fromDecimals); + const decimalDiff = fromDecimals - toDecimals; + + if (decimalDiff > 0) { + return BigInt(parsedValue) / BigInt(10) ** BigInt(decimalDiff); + } else if (decimalDiff < 0) { + return BigInt(parsedValue) * BigInt(10) ** BigInt(Math.abs(decimalDiff)); + } + + return BigInt(parsedValue); +} diff --git a/packages/swapper/src/mayan/evm.ts b/packages/swapper/src/mayan/evm.ts new file mode 100644 index 0000000..677efa8 --- /dev/null +++ b/packages/swapper/src/mayan/evm.ts @@ -0,0 +1,13 @@ +import { QuoteRequest, QuoteData } from "@gemwallet/types"; +import { Quote as MayanQuote, getSwapFromEvmTxPayload } from "@mayanfinance/swap-sdk"; + +export function buildEvmQuoteData(request: QuoteRequest, routeData: MayanQuote): QuoteData { + const signerChainId = routeData.fromToken.chainId; + const swapData = getSwapFromEvmTxPayload(routeData, request.from_address, request.to_address, { evm: request.referral_address }, request.from_address, signerChainId, null, null); + const value = BigInt(swapData.value || 0); + return { + to: swapData.to?.toString() || "", + value: value.toString(), + data: swapData.data?.toString() || "0x", + }; +} diff --git a/packages/swapper/src/mayan/index.test.ts b/packages/swapper/src/mayan/index.test.ts new file mode 100644 index 0000000..b589f22 --- /dev/null +++ b/packages/swapper/src/mayan/index.test.ts @@ -0,0 +1,21 @@ +import { parseDecimals } from "../bigint"; + +describe('Fetch Quote', () => { + it('Parse decimal string to BigInt string', () => { + const output_value = "0.1384511931777"; + const output_min_value = "0.13641535"; + + const output_value_bigint = parseDecimals(output_value, 9); + const output_min_value_bigint = parseDecimals(output_min_value, 9); + + expect(output_value_bigint.toString()).toEqual("138451193"); + expect(output_min_value_bigint.toString()).toEqual("136415350"); + }); + + it('Convert hex BigInt string to decimal', () => { + const hexValue = "0x2386f26fc10000"; + const expectedDecimalValue = BigInt(hexValue).toString(); + expect(expectedDecimalValue).toEqual("10000000000000000"); + }); +}); + diff --git a/packages/swapper/src/mayan/index.ts b/packages/swapper/src/mayan/index.ts index b824060..b6ae1b0 100644 --- a/packages/swapper/src/mayan/index.ts +++ b/packages/swapper/src/mayan/index.ts @@ -1,10 +1,11 @@ -import { fetchQuote, getSwapFromEvmTxPayload, ChainName, QuoteParams, QuoteOptions, Quote as MayanQuote, createSwapFromSolanaInstructions, ReferrerAddresses } from "@mayanfinance/swap-sdk"; +import { fetchQuote, ChainName, QuoteParams, QuoteOptions, Quote as MayanQuote } from "@mayanfinance/swap-sdk"; import { QuoteRequest, Quote, QuoteData, Asset, Chain } from "@gemwallet/types"; import { Protocol } from "../protocol"; -import { Connection, MessageV0, PublicKey, Transaction, VersionedTransaction } from "@solana/web3.js"; +import { buildEvmQuoteData } from "./evm"; +import { buildSolanaQuoteData } from "./solana"; +import { parseDecimals } from "../bigint"; export class MayanProvider implements Protocol { - private rpcEndpoint: string; constructor(rpcEndpoint: string) { this.rpcEndpoint = rpcEndpoint; @@ -12,19 +13,17 @@ export class MayanProvider implements Protocol { mapAssetToTokenId(asset: Asset): string { if (asset.isNative()) { - if (asset.chain === Chain.SOLANA) { - return "So11111111111111111111111111111111111111112"; - } else { - return "0x0000000000000000000000000000000000000000"; - } + return "0x0000000000000000000000000000000000000000"; } return asset.tokenId!; } mapChainToName(chain: Chain): ChainName { switch (chain) { - case Chain.SMARTCHAIN: + case Chain.SmartChain: return "bsc"; + case Chain.AvalancheC: + return "avalance" as ChainName; default: return chain as ChainName; } @@ -44,15 +43,19 @@ export class MayanProvider implements Protocol { referrer: quoteRequest.referral_address, referrerBps: quoteRequest.referral_bps } + + // explicitly set which types of quotes we want to fetch const options: QuoteOptions = { + "wormhole": true, "swift": true, - "fastMctp": false, + "gasless": false, + "mctp": true, + "shuttle": false, + "fastMctp": true, + "onlyDirect": false, } - const timestamp = Date.now(); const quotes = await fetchQuote(params, options); - const latency = Date.now() - timestamp; - console.log("Mayan quote latency: ", latency); if (!quotes || quotes.length === 0) { throw new Error("No quotes available"); @@ -60,10 +63,13 @@ export class MayanProvider implements Protocol { const quote = quotes[0]; + const output_value = parseDecimals(quote.expectedAmountOut, quote.toToken.decimals); + const output_min_value = parseDecimals(quote.minAmountOut, quote.toToken.decimals); + return { quote: quoteRequest, - output_value: quote.expectedAmountOut.toString(), - output_min_value: quote.minAmountOut.toString(), + output_value: output_value.toString(), + output_min_value: output_min_value.toString(), route_data: quote }; } @@ -71,110 +77,10 @@ export class MayanProvider implements Protocol { async get_quote_data(quote: Quote): Promise { const fromAsset = Asset.fromString(quote.quote.from_asset.toString()); - if (fromAsset.chain === Chain.SOLANA) { - return this.buildSolanaQuoteData(quote.quote, quote.route_data as MayanQuote); + if (fromAsset.chain === Chain.Solana) { + return buildSolanaQuoteData(quote.quote, quote.route_data as MayanQuote, this.rpcEndpoint); } else { - return this.buildEvmQuoteData(quote.quote, quote.route_data as MayanQuote); + return buildEvmQuoteData(quote.quote, quote.route_data as MayanQuote); } } - - buildEvmQuoteData(request: QuoteRequest, routeData: MayanQuote): QuoteData { - const signerChainId = routeData.fromToken.chainId; - const swapData = getSwapFromEvmTxPayload(routeData, request.from_address, request.to_address, { evm: request.referral_address }, request.from_address, signerChainId, null, null); - - return { - to: swapData.to?.toString() || "", - value: swapData.value?.toString() || "0", - data: swapData.data?.toString() || "0x", - }; - } - - async buildSolanaQuoteData(request: QuoteRequest, routeData: MayanQuote): Promise { - const connection = new Connection(this.rpcEndpoint); - const referrerAddresses = { solana: request.referral_address }; - const { serializedTrx } = await this.prepareSolanaSwapTransaction( - routeData, - request.from_address, - request.to_address, - referrerAddresses, - connection - ); - - return { - to: "", - value: "0", - data: Buffer.from(serializedTrx).toString("base64"), - }; - } - - async prepareSolanaSwapTransaction( - quote: MayanQuote, - swapperWalletAddress: string, - destinationAddress: string, - referrerAddresses: ReferrerAddresses, - connection: Connection, - ): Promise<{ - serializedTrx: Uint8Array, - additionalInfo: { - blockhash: string, - lastValidBlockHeight: number, - isVersionedTransaction: boolean, - feePayer: string, - } - }> { - - const { - instructions, - signers, - lookupTables, - } = await createSwapFromSolanaInstructions( - quote, swapperWalletAddress, destinationAddress, - referrerAddresses, connection, { separateSwapTx: false }); - - const swapper = new PublicKey(swapperWalletAddress); - const feePayer = quote.gasless ? new PublicKey(quote.relayer) : swapper; - - const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash(); - - let serializedTrx: Uint8Array; - let isVersionedTransaction = false; - - if (lookupTables.length > 0) { - isVersionedTransaction = true; - const message = MessageV0.compile({ - instructions, - payerKey: feePayer, - recentBlockhash: blockhash, - addressLookupTableAccounts: lookupTables, - }); - const transaction = new VersionedTransaction(message); - transaction.sign(signers); - serializedTrx = transaction.serialize(); - } else { - const transaction = new Transaction(); - transaction.recentBlockhash = blockhash; - transaction.feePayer = feePayer; - - instructions.forEach(instruction => transaction.add(instruction)); - - if (signers.length > 0) { - transaction.partialSign(...signers); - } - - serializedTrx = transaction.serialize({ - requireAllSignatures: false, - verifySignatures: false, - }); - } - - return { - serializedTrx, - additionalInfo: { - blockhash, - lastValidBlockHeight, - isVersionedTransaction, - feePayer: feePayer.toBase58(), - } - }; - } } diff --git a/packages/swapper/src/mayan/solana.ts b/packages/swapper/src/mayan/solana.ts new file mode 100644 index 0000000..624d666 --- /dev/null +++ b/packages/swapper/src/mayan/solana.ts @@ -0,0 +1,91 @@ +import { QuoteRequest, QuoteData } from "@gemwallet/types"; +import { Quote as MayanQuote, ReferrerAddresses, createSwapFromSolanaInstructions } from "@mayanfinance/swap-sdk"; +import { Connection, MessageV0, PublicKey, Transaction, VersionedTransaction } from "@solana/web3.js"; + +export async function buildSolanaQuoteData(request: QuoteRequest, routeData: MayanQuote, rpcEndpoint: string): Promise { + const connection = new Connection(rpcEndpoint); + const referrerAddresses = { solana: request.referral_address }; + const { serializedTrx } = await prepareSolanaSwapTransaction( + routeData, + request.from_address, + request.to_address, + referrerAddresses, + connection + ); + + return { + to: "", + value: "0", + data: Buffer.from(serializedTrx).toString("base64"), + }; +} + +async function prepareSolanaSwapTransaction( + quote: MayanQuote, + swapperWalletAddress: string, + destinationAddress: string, + referrerAddresses: ReferrerAddresses, + connection: Connection, +): Promise<{ + serializedTrx: Uint8Array, + additionalInfo: { + blockhash: string, + lastValidBlockHeight: number, + isVersionedTransaction: boolean, + feePayer: string, + } +}> { + const { + instructions, + signers, + lookupTables, + } = await createSwapFromSolanaInstructions( + quote, swapperWalletAddress, destinationAddress, + referrerAddresses, connection, { separateSwapTx: false }); + + const swapper = new PublicKey(swapperWalletAddress); + const feePayer = quote.gasless ? new PublicKey(quote.relayer) : swapper; + + const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash(); + + let serializedTrx: Uint8Array; + let isVersionedTransaction = false; + + if (lookupTables.length > 0) { + isVersionedTransaction = true; + const message = MessageV0.compile({ + instructions, + payerKey: feePayer, + recentBlockhash: blockhash, + addressLookupTableAccounts: lookupTables, + }); + const transaction = new VersionedTransaction(message); + transaction.sign(signers); + serializedTrx = transaction.serialize(); + } else { + const transaction = new Transaction(); + transaction.recentBlockhash = blockhash; + transaction.feePayer = feePayer; + + instructions.forEach(instruction => transaction.add(instruction)); + + if (signers.length > 0) { + transaction.partialSign(...signers); + } + + serializedTrx = transaction.serialize({ + requireAllSignatures: false, + verifySignatures: false, + }); + } + + return { + serializedTrx, + additionalInfo: { + blockhash, + lastValidBlockHeight, + isVersionedTransaction, + feePayer: feePayer.toBase58(), + } + }; +} \ No newline at end of file diff --git a/packages/types/package.json b/packages/types/package.json index df095c5..e5dcf70 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -21,4 +21,4 @@ "files": [ "dist" ] -} +} \ No newline at end of file diff --git a/packages/types/src/asset.test.ts b/packages/types/src/asset.test.ts index 414ce93..e3b865f 100644 --- a/packages/types/src/asset.test.ts +++ b/packages/types/src/asset.test.ts @@ -1,17 +1,17 @@ -import { Asset, Chain } from './asset'; +import { Asset } from './asset'; +import { Chain } from './primitives'; describe('Asset', () => { - // ...existing test code from types.test.ts for Asset... describe('constructor', () => { it('should create Asset with chain only', () => { - const asset = new Asset(Chain.TON); - expect(asset.chain).toBe(Chain.TON); + const asset = new Asset(Chain.Ton); + expect(asset.chain).toBe(Chain.Ton); expect(asset.tokenId).toBeUndefined(); }); it('should create Asset with chain and tokenId', () => { - const asset = new Asset(Chain.TON, 'TOKEN123'); - expect(asset.chain).toBe(Chain.TON); + const asset = new Asset(Chain.Ton, 'TOKEN123'); + expect(asset.chain).toBe(Chain.Ton); expect(asset.tokenId).toBe('TOKEN123'); }); }); @@ -19,55 +19,55 @@ describe('Asset', () => { describe('fromString', () => { it('should parse native asset string', () => { const asset = Asset.fromString('ton'); - expect(asset.chain).toBe(Chain.TON); + expect(asset.chain).toBe(Chain.Ton); expect(asset.tokenId).toBeUndefined(); }); it('should parse token asset string', () => { const asset = Asset.fromString('ton_TOKEN123'); - expect(asset.chain).toBe(Chain.TON); + expect(asset.chain).toBe(Chain.Ton); expect(asset.tokenId).toBe('TOKEN123'); }); it('should handle tokenId with underscores', () => { const asset = Asset.fromString('ton_TOKEN_123_ABC'); - expect(asset.chain).toBe(Chain.TON); + expect(asset.chain).toBe(Chain.Ton); expect(asset.tokenId).toBe('TOKEN_123_ABC'); }); }); describe('toString', () => { it('should convert native asset to string', () => { - const asset = new Asset(Chain.TON); + const asset = new Asset(Chain.Ton); expect(asset.toString()).toBe('ton'); }); it('should convert token asset to string', () => { - const asset = new Asset(Chain.TON, 'TOKEN123'); + const asset = new Asset(Chain.Ton, 'TOKEN123'); expect(asset.toString()).toBe('ton_TOKEN123'); }); }); describe('isNative', () => { it('should return true for native asset', () => { - const asset = new Asset(Chain.TON); + const asset = new Asset(Chain.Ton); expect(asset.isNative()).toBe(true); }); it('should return false for token asset', () => { - const asset = new Asset(Chain.TON, 'TOKEN123'); + const asset = new Asset(Chain.Ton, 'TOKEN123'); expect(asset.isNative()).toBe(false); }); }); describe('toJSON', () => { it('should serialize native asset', () => { - const asset = new Asset(Chain.TON); + const asset = new Asset(Chain.Ton); expect(asset.toJSON()).toBe('ton'); }); it('should serialize token asset', () => { - const asset = new Asset(Chain.TON, 'TOKEN123'); + const asset = new Asset(Chain.Ton, 'TOKEN123'); expect(asset.toJSON()).toBe('ton_TOKEN123'); }); }); diff --git a/packages/types/src/asset.ts b/packages/types/src/asset.ts index e13a464..e3bca10 100644 --- a/packages/types/src/asset.ts +++ b/packages/types/src/asset.ts @@ -1,20 +1,10 @@ -export enum Chain { - TON = 'ton', - SOLANA = 'solana', - ETHEREUM = 'ethereum', - AVALANCHE = 'avalanche', - POLYGON = 'polygon', - BASE = 'base', - ARBITRUM = 'arbitrum', - OPTIMISM = 'optimism', - SMARTCHAIN = 'smartchain', -} +import { Chain } from './primitives'; export class Asset { constructor( public chain: Chain, public tokenId?: string - ) {} + ) { } static fromString(asset: string): Asset { const [chain, ...rest] = asset.split('_'); diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index e323270..6c9b97b 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -1,2 +1,3 @@ export * from './asset'; export * from './quotes'; +export { Chain } from './primitives'; \ No newline at end of file diff --git a/packages/types/src/primitives.ts b/packages/types/src/primitives.ts new file mode 100644 index 0000000..ed9e890 --- /dev/null +++ b/packages/types/src/primitives.ts @@ -0,0 +1,1059 @@ +/* + Generated by typeshare 1.13.2 +*/ + +export enum Chain { + Bitcoin = "bitcoin", + BitcoinCash = "bitcoincash", + Litecoin = "litecoin", + Ethereum = "ethereum", + SmartChain = "smartchain", + Solana = "solana", + Polygon = "polygon", + Thorchain = "thorchain", + Cosmos = "cosmos", + Osmosis = "osmosis", + Arbitrum = "arbitrum", + Ton = "ton", + Tron = "tron", + Doge = "doge", + Optimism = "optimism", + Aptos = "aptos", + Base = "base", + AvalancheC = "avalanchec", + Sui = "sui", + Xrp = "xrp", + OpBNB = "opbnb", + Fantom = "fantom", + Gnosis = "gnosis", + Celestia = "celestia", + Injective = "injective", + Sei = "sei", + Manta = "manta", + Blast = "blast", + Noble = "noble", + ZkSync = "zksync", + Linea = "linea", + Mantle = "mantle", + Celo = "celo", + Near = "near", + World = "world", + Stellar = "stellar", + Sonic = "sonic", + Algorand = "algorand", + Polkadot = "polkadot", + Cardano = "cardano", + Abstract = "abstract", + Berachain = "berachain", + Ink = "ink", + Unichain = "unichain", + Hyperliquid = "hyperliquid", + Monad = "monad", +} + +export interface Account { + chain: Chain; + address: string; + derivationPath: string; + extendedPublicKey?: string; +} + +export interface AssetId { + chain: Chain; + tokenId?: string; +} + +export enum AssetType { + NATIVE = "NATIVE", + ERC20 = "ERC20", + BEP20 = "BEP20", + SPL = "SPL", + TRC20 = "TRC20", + TOKEN = "TOKEN", + IBC = "IBC", + JETTON = "JETTON", + SYNTH = "SYNTH", + ASA = "ASA", +} + +export interface Asset { + id: AssetId; + name: string; + symbol: string; + decimals: number; + type: AssetType; +} + +export interface AssetAddress { + asset: Asset; + address: string; +} + +export interface AssetProperties { + isEnabled: boolean; + isBuyable: boolean; + isSellable: boolean; + isSwapable: boolean; + isStakeable: boolean; + stakingApr?: number; +} + +export interface AssetScore { + rank: number; +} + +export interface AssetBasic { + asset: Asset; + properties: AssetProperties; + score: AssetScore; +} + +export interface Balance { + available: BigInteger; + frozen: BigInteger; + locked: BigInteger; + staked: BigInteger; + pending: BigInteger; + rewards: BigInteger; +} + +export interface Price { + price: number; + priceChangePercentage24h: number; +} + +export enum PriceAlertDirection { + Up = "up", + Down = "down", +} + +export interface PriceAlert { + assetId: string; + currency: string; + price?: number; + pricePercentChange?: number; + priceDirection?: PriceAlertDirection; + lastNotifiedAt?: Date; +} + +export interface AssetMetaData { + isEnabled: boolean; + isBuyEnabled: boolean; + isSellEnabled: boolean; + isSwapEnabled: boolean; + isStakeEnabled: boolean; + isPinned: boolean; + isActive: boolean; + stakingApr?: number; +} + +export interface AssetData { + asset: Asset; + balance: Balance; + account: Account; + price?: Price; + price_alerts: PriceAlert[]; + metadata: AssetMetaData; +} + +export interface AssetLink { + name: string; + url: string; +} + +export interface AssetFull { + asset: Asset; + properties: AssetProperties; + score: AssetScore; + links: AssetLink[]; +} + +export interface AssetMarket { + marketCap?: number; + marketCapFdv?: number; + marketCapRank?: number; + totalVolume?: number; + circulatingSupply?: number; + totalSupply?: number; + maxSupply?: number; +} + +export interface AssetMarketPrice { + price?: Price; + market?: AssetMarket; +} + +export interface AssetPrice { + assetId: string; + price: number; + priceChangePercentage24h: number; +} + +export interface AssetPrices { + currency: string; + prices: AssetPrice[]; +} + +export interface AssetPricesRequest { + currency?: string; + assetIds: string[]; +} + +export enum WalletType { + multicoin = "multicoin", + single = "single", + private_key = "privateKey", + view = "view", +} + +export interface Wallet { + id: string; + name: string; + index: number; + type: WalletType; + accounts: Account[]; + order: number; + isPinned: boolean; + imageUrl?: string; +} + +export enum BannerEvent { + Stake = "stake", + AccountActivation = "accountActivation", + EnableNotifications = "enableNotifications", + AccountBlockedMultiSignature = "accountBlockedMultiSignature", + ActivateAsset = "activateAsset", +} + +export enum BannerState { + Active = "active", + Cancelled = "cancelled", + AlwaysActive = "alwaysActive", +} + +export interface Banner { + wallet?: Wallet; + asset?: Asset; + chain?: Chain; + event: BannerEvent; + state: BannerState; +} + +export interface BlockExplorerLink { + name: string; + link: string; +} + +export enum NodeState { + Active = "active", + Inactive = "inactive", +} + +export interface Node { + url: string; + status: NodeState; + priority: number; +} + +export interface ChainNode { + chain: string; + node: Node; +} + +export interface ChainNodes { + chain: string; + nodes: Node[]; +} + +export interface ChartValue { + timestamp: number; + value: number; +} + +export interface Charts { + price?: Price; + market?: AssetMarket; + prices: ChartValue[]; + marketCaps: ChartValue[]; + totalVolumes: ChartValue[]; +} + +export enum PlatformStore { + AppStore = "appStore", + GooglePlay = "googlePlay", + Fdroid = "fdroid", + Huawei = "huawei", + SolanaStore = "solanaStore", + SamsungStore = "samsungStore", + ApkUniversal = "apkUniversal", + Local = "local", +} + +export interface Release { + version: string; + store: PlatformStore; + upgradeRequired: boolean; +} + +export interface ConfigVersions { + fiatOnRampAssets: number; + fiatOffRampAssets: number; + swapAssets: number; +} + +export interface ConfigResponse { + releases: Release[]; + versions: ConfigVersions; +} + +export enum DelegationState { + Active = "active", + Pending = "pending", + Undelegating = "undelegating", + Inactive = "inactive", + Activating = "activating", + Deactivating = "deactivating", + AwaitingWithdrawal = "awaitingwithdrawal", +} + +export interface DelegationBase { + assetId: AssetId; + state: DelegationState; + balance: string; + shares: string; + rewards: string; + completionDate?: Date; + delegationId: string; + validatorId: string; +} + +export interface DelegationValidator { + chain: Chain; + id: string; + name: string; + isActive: boolean; + commision: number; + apr: number; +} + +export interface Delegation { + base: DelegationBase; + validator: DelegationValidator; + price?: Price; +} + +export enum Platform { + IOS = "ios", + Android = "android", +} + +export interface Device { + id: string; + platform: Platform; + platformStore?: PlatformStore; + token: string; + locale: string; + version: string; + currency: string; + isPushEnabled: boolean; + isPriceAlertsEnabled?: boolean; + subscriptionsVersion: number; +} + +export interface EIP712Domain { + name: string; + version: string; + chainId: number; + verifyingContract: string; +} + +export interface EIP712Type { + name: string; + type: string; +} + +export interface ERC2612Permit { + owner: string; + spender: string; + value: string; + nonce: string; + deadline: string; +} + +export interface ERC2612Types { + EIP712Domain: EIP712Type[]; + Permit: EIP712Type[]; +} + +export interface ERC2612PermitMessage { + types: ERC2612Types; + primaryType: string; + domain: EIP712Domain; + message: ERC2612Permit; +} + +export interface FiatAssets { + version: number; + assetIds: string[]; +} + +export interface FiatProvider { + id: string; + name: string; + imageUrl: string; +} + +export enum FiatQuoteType { + Buy = "buy", + Sell = "sell", +} + +export interface FiatQuote { + provider: FiatProvider; + type: FiatQuoteType; + fiatAmount: number; + fiatCurrency: string; + cryptoAmount: number; + cryptoValue: string; + redirectUrl: string; +} + +export interface FiatQuoteError { + provider: string; + error: string; +} + +export interface FiatQuoteRequest { + assetId: string; + type: FiatQuoteType; + fiatCurrency: string; + fiatAmount?: number; + cryptoValue?: string; + walletAddress: string; +} + +export interface FiatQuotes { + quotes: FiatQuote[]; +} + +export interface MarketDominance { + assetId: string; + dominance: number; +} + +export interface MarketsAssets { + trending: string[]; + gainers: string[]; + losers: string[]; +} + +export interface Markets { + marketCap: number; + marketCapChangePercentage24h: number; + assets: MarketsAssets; + dominance: MarketDominance[]; + totalVolume24h: number; +} + +export enum NFTType { + ERC721 = "erc721", + ERC1155 = "erc1155", + SPL = "spl", + JETTON = "jetton", +} + +export interface NFTResource { + url: string; + mimeType: string; +} + +export interface NFTImages { + preview: NFTResource; +} + +export interface NFTAttribute { + name: string; + value: string; + percentage?: number; +} + +export interface NFTAsset { + id: string; + collectionId: string; + contractAddress?: string; + tokenId: string; + tokenType: NFTType; + name: string; + description?: string; + chain: Chain; + resource: NFTResource; + images: NFTImages; + attributes: NFTAttribute[]; +} + +export interface NFTCollection { + id: string; + name: string; + description?: string; + chain: Chain; + contractAddress: string; + images: NFTImages; + isVerified: boolean; + links: AssetLink[]; +} + +export interface NFTAssetData { + collection: NFTCollection; + asset: NFTAsset; +} + +export interface NFTAssetId { + chain: Chain; + contractAddress: string; + tokenId: string; +} + +export interface NFTData { + collection: NFTCollection; + assets: NFTAsset[]; +} + +export interface NFTImageOld { + imageUrl: string; + previewImageUrl: string; + originalSourceUrl: string; +} + +export interface NameRecord { + name: string; + chain: Chain; + address: string; + provider: string; +} + +export interface NodesResponse { + version: number; + nodes: ChainNodes[]; +} + +export interface PriceAlertData { + asset: Asset; + price?: Price; + priceAlert: PriceAlert; +} + +export interface PriceData { + asset: Asset; + price?: Price; + priceAlerts: PriceAlert[]; + market?: AssetMarket; + links: AssetLink[]; +} + +export interface PushNotificationAsset { + assetId: string; +} + +export enum PushNotificationTypes { + Test = "test", + Transaction = "transaction", + Asset = "asset", + PriceAlert = "priceAlert", + BuyAsset = "buyAsset", + SwapAsset = "swapAsset", +} + +export interface PushNotificationPayloadType { + type: PushNotificationTypes; +} + +export interface PushNotificationSwapAsset { + fromAssetId: string; + toAssetId: string; +} + +export interface PushNotificationTransaction { + walletIndex: number; + assetId: string; + transactionId: string; +} + +export interface ResponseError { + error: string; +} + +export interface ResponseResult { + data: T; + error?: ResponseError; +} + +export interface ScanAddressTarget { + chain: Chain; + address: string; +} + +export interface ScanTransaction { + isMalicious: boolean; + isMemoRequired: boolean; +} + +export enum TransactionType { + Transfer = "transfer", + TransferNFT = "transferNFT", + Swap = "swap", + TokenApproval = "tokenApproval", + StakeDelegate = "stakeDelegate", + StakeUndelegate = "stakeUndelegate", + StakeRewards = "stakeRewards", + StakeRedelegate = "stakeRedelegate", + StakeWithdraw = "stakeWithdraw", + AssetActivation = "assetActivation", + SmartContractCall = "smartContractCall", +} + +export interface ScanTransactionPayload { + deviceId: string; + walletIndex: number; + origin: ScanAddressTarget; + target: ScanAddressTarget; + website?: string; + type: TransactionType; +} + +export enum SignDigestType { + Sign = "sign", + Eip191 = "eip191", + Eip712 = "eip712", + Base58 = "base58", +} + +export interface SignMessage { + type: SignDigestType; + data: Uint8Array; +} + +export interface StakeValidator { + id: string; + name: string; +} + +export interface Subscription { + wallet_index: number; + chain: Chain; + address: string; +} + +export enum TransactionState { + Pending = "pending", + Confirmed = "confirmed", + Failed = "failed", + Reverted = "reverted", +} + +export enum TransactionDirection { + SelfTransfer = "self", + Outgoing = "outgoing", + Incoming = "incoming", +} + +export interface TransactionInput { + address: string; + value: string; +} + +export interface Transaction { + id: string; + hash: string; + assetId: AssetId; + from: string; + to: string; + contract?: string; + type: TransactionType; + state: TransactionState; + blockNumber: string; + sequence: string; + fee: string; + feeAssetId: AssetId; + value: string; + memo?: string; + direction: TransactionDirection; + utxoInputs: TransactionInput[]; + utxoOutputs: TransactionInput[]; + metadata?: string | null; + createdAt: Date; +} + +export interface TransactionExtended { + transaction: Transaction; + asset: Asset; + feeAsset: Asset; + price?: Price; + feePrice?: Price; + assets: Asset[]; + prices: AssetPrice[]; +} + +export interface TransactionNFTTransferMetadata { + assetId: string; +} + +export interface TransactionSwapMetadata { + fromAsset: AssetId; + fromValue: string; + toAsset: AssetId; + toValue: string; +} + +export interface TransactionsFetchOption { + wallet_index: number; + asset_id?: string; + from_timestamp?: number; +} + +export interface UTXO { + transaction_id: string; + vout: number; + value: string; + address: string; +} + +export interface WCEthereumTransaction { + chainId?: string; + from: string; + to: string; + value?: string; + gas?: string; + gasLimit?: string; + gasPrice?: string; + maxFeePerGas?: string; + maxPriorityFeePerGas?: string; + nonce?: string; + data?: string; +} + +export interface WCSolanaSignMessage { + message: string; + pubkey: string; +} + +export interface WCSolanaSignMessageResult { + signature: string; +} + +export interface WCSolanaTransaction { + transaction: string; +} + +export enum WalletConnectionState { + Started = "started", + Active = "active", + Expired = "expired", +} + +export interface WalletConnectionSessionAppMetadata { + name: string; + description: string; + url: string; + icon: string; + redirectNative?: string; + redirectUniversal?: string; +} + +export interface WalletConnectionSession { + id: string; + sessionId: string; + state: WalletConnectionState; + chains: Chain[]; + createdAt: Date; + expireAt: Date; + metadata: WalletConnectionSessionAppMetadata; +} + +export interface WalletConnection { + session: WalletConnectionSession; + wallet: Wallet; +} + +export interface WalletConnectionSessionProposal { + defaultWallet: Wallet; + wallets: Wallet[]; + metadata: WalletConnectionSessionAppMetadata; +} + +export interface WalletId { + id: string; +} + +export enum AssetRank { + High = "high", + Medium = "medium", + Low = "low", + Trivial = "trivial", + Unknown = "unknown", + Inactive = "inactive", + Abandoned = "abandoned", + Suspended = "suspended", + Migrated = "migrated", + Deprecated = "deprecated", + Spam = "spam", + Fradulent = "fradulent", +} + +export enum AssetSubtype { + NATIVE = "NATIVE", + TOKEN = "TOKEN", +} + +export enum AssetTag { + Trending = "trending", + TrendingFiatPurchase = "trending_fiat_purchase", + Gainers = "gainers", + Losers = "losers", + New = "new", + Stablecoins = "stablecoins", +} + +export enum BalanceType { + available = "available", + locked = "locked", + frozen = "frozen", + staked = "staked", + pending = "pending", + rewards = "rewards", + reserved = "reserved", +} + +export enum BitcoinChain { + Bitcoin = "bitcoin", + BitcoinCash = "bitcoincash", + Litecoin = "litecoin", + Doge = "doge", +} + +export enum ChainType { + Ethereum = "ethereum", + Bitcoin = "bitcoin", + Solana = "solana", + Cosmos = "cosmos", + Ton = "ton", + Tron = "tron", + Aptos = "aptos", + Sui = "sui", + Xrp = "xrp", + Near = "near", + Stellar = "stellar", + Algorand = "algorand", + Polkadot = "polkadot", + Cardano = "cardano", +} + +export enum ChartPeriod { + Hour = "hour", + Day = "day", + Week = "week", + Month = "month", + Quarter = "quarter", + Year = "year", + All = "all", +} + +export enum CosmosChain { + Cosmos = "cosmos", + Osmosis = "osmosis", + Celestia = "celestia", + Thorchain = "thorchain", + Injective = "injective", + Sei = "sei", + Noble = "noble", +} + +export enum CosmosDenom { + Rune = "rune", + Uatom = "uatom", + Uosmo = "uosmo", + Utia = "utia", + Inj = "inj", + Usei = "usei", + Uusdc = "uusdc", +} + +export enum Currency { + MXN = "MXN", + CHF = "CHF", + CNY = "CNY", + THB = "THB", + HUF = "HUF", + AUD = "AUD", + IDR = "IDR", + RUB = "RUB", + ZAR = "ZAR", + EUR = "EUR", + NZD = "NZD", + SAR = "SAR", + SGD = "SGD", + BMD = "BMD", + KWD = "KWD", + HKD = "HKD", + JPY = "JPY", + GBP = "GBP", + DKK = "DKK", + KRW = "KRW", + PHP = "PHP", + CLP = "CLP", + TWD = "TWD", + PKR = "PKR", + BRL = "BRL", + CAD = "CAD", + BHD = "BHD", + MMK = "MMK", + VEF = "VEF", + VND = "VND", + CZK = "CZK", + TRY = "TRY", + INR = "INR", + ARS = "ARS", + BDT = "BDT", + NOK = "NOK", + USD = "USD", + LKR = "LKR", + ILS = "ILS", + PLN = "PLN", + NGN = "NGN", + UAH = "UAH", + XDR = "XDR", + MYR = "MYR", + AED = "AED", + SEK = "SEK", +} + +export enum EVMChain { + Ethereum = "ethereum", + SmartChain = "smartchain", + Polygon = "polygon", + Arbitrum = "arbitrum", + Optimism = "optimism", + Base = "base", + AvalancheC = "avalanchec", + OpBNB = "opbnb", + Fantom = "fantom", + Gnosis = "gnosis", + Manta = "manta", + Blast = "blast", + ZkSync = "zksync", + Linea = "linea", + Mantle = "mantle", + Celo = "celo", + World = "world", + Sonic = "sonic", + Abstract = "abstract", + Berachain = "berachain", + Ink = "ink", + Unichain = "unichain", + Hyperliquid = "hyperliquid", + Monad = "monad", +} + +export enum EncodingType { + Hex = "Hex", + Base58 = "Base58", +} + +export enum FeePriority { + Slow = "slow", + Normal = "normal", + Fast = "fast", +} + +export enum FeeUnitType { + SatVb = "satVb", + Gwei = "gwei", + Native = "native", +} + +export enum LinkType { + X = "x", + Discord = "discord", + Reddit = "reddit", + Telegram = "telegram", + GitHub = "github", + YouTube = "youtube", + Facebook = "facebook", + Website = "website", + Coingecko = "coingecko", + OpenSea = "opensea", + Instagram = "instagram", + MagicEden = "magiceden", + CoinMarketCap = "coinmarketcap", + TikTok = "tiktok", +} + +export enum NameProvider { + Ud = "ud", + Ens = "ens", + Sns = "sns", + Ton = "ton", + Tree = "tree", + Spaceid = "spaceid", + Eths = "eths", + Did = "did", + Suins = "suins", + Aptos = "aptos", + Injective = "injective", + Icns = "icns", + Lens = "lens", + Bns = "bns", +} + +export enum PriceAlertNotificationType { + Auto = "Auto", + Price = "Price", + PricePercentChange = "PricePercentChange", +} + +export enum SolanaTokenProgramId { + Token = "token", + Token2022 = "token2022", +} + +export enum StakeChain { + Cosmos = "cosmos", + Osmosis = "osmosis", + Injective = "injective", + Sei = "sei", + Celestia = "celestia", + Solana = "solana", + Sui = "sui", + SmartChain = "smartchain", + Tron = "tron", +} + +export enum WalletConnectCAIP2 { + Eip155 = "eip155", + Solana = "solana", + Cosmos = "cosmos", + Algorand = "algorand", +} + +export enum WalletConnectionEvents { + connect = "connect", + disconnect = "disconnect", + accounts_changed = "accountsChanged", + chain_changed = "chainChanged", +} + +export enum WalletConnectionMethods { + eth_chain_id = "eth_chainId", + eth_sign = "eth_sign", + personal_sign = "personal_sign", + eth_sign_typed_data = "eth_signTypedData", + eth_sign_typed_data_v4 = "eth_signTypedData_v4", + eth_sign_transaction = "eth_signTransaction", + eth_send_transaction = "eth_sendTransaction", + eth_send_raw_transaction = "eth_sendRawTransaction", + wallet_switch_ethereum_chain = "wallet_switchEthereumChain", + wallet_add_ethereum_chain = "wallet_addEthereumChain", + solana_sign_message = "solana_signMessage", + solana_sign_transaction = "solana_signTransaction", + solana_sign_and_send_transaction = "solana_signAndSendTransaction", +} + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2c2dd06..2b27bc2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -75,6 +75,9 @@ importers: '@ton/ton': specifier: 15.2.1 version: 15.2.1(@ton/core@0.60.1(@ton/crypto@3.3.0))(@ton/crypto@3.3.0) + ethers: + specifier: 6.13.5 + version: 6.13.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) devDependencies: '@types/jest': specifier: 29.5.14