From 8b0c0c542c04a857d42009abc3eb3dbf148052e8 Mon Sep 17 00:00:00 2001 From: Imamah-Zafar <88320460+Imamah-Zafar@users.noreply.github.com> Date: Fri, 11 Nov 2022 18:13:47 +0500 Subject: [PATCH 1/4] Add stacks url check api call --- api/stacks.ts | 21 ++++++++++++++++++++- types/api/stacks/assets.ts | 11 +++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/api/stacks.ts b/api/stacks.ts index 8862b4ca..f445e707 100644 --- a/api/stacks.ts +++ b/api/stacks.ts @@ -34,7 +34,7 @@ import { import {StacksMainnet, StacksTestnet} from '@stacks/network'; import { AnchorMode, estimateTransfer, makeUnsignedSTXTokenTransfer, UnsignedTokenTransferOptions, } from '@stacks/transactions'; import { getNonce, setNonce } from '../transactions'; -import { AddressToBnsResponse } from '../types/api/stacks/assets'; +import { AddressToBnsResponse, PoxData } from '../types/api/stacks/assets'; export async function getTransaction(txid: string, network: SettingsNetwork): Promise { return fetch(`${network.address}/extended/v1/tx/${txid}`, { @@ -393,3 +393,22 @@ export async function getBnsName(stxAddress: string, network: SettingsNetwork,) return undefined; }); } + +export async function getStacksInfo(network:string){ + const url = `${network}/v2/info`; + console.log("inisde") + console.log(network) + return axios + .get(url, { + timeout: 30000, + }) + .then((response) => { + console.log("response ") + console.log(response) + return response?.data; + }) + .catch((error) => { + return undefined; + }); + +} diff --git a/types/api/stacks/assets.ts b/types/api/stacks/assets.ts index ae5572fe..49dedde4 100644 --- a/types/api/stacks/assets.ts +++ b/types/api/stacks/assets.ts @@ -59,3 +59,14 @@ export interface NftEventsResponse { export interface AddressToBnsResponse { names: string[]; } +export interface PoxData { + contract_id: string; + first_burnchain_block_height: number; + min_amount_ustx: string; + prepare_cycle_length: number; + rejection_fraction: number; + reward_cycle_id: number; + rejection_votes_left_required: string; + total_liquid_supply_ustx: string; + next_reward_cycle_in: number; +} From dc213b745b5c0a4d1d3adc432630d4cfe5c0f14c Mon Sep 17 00:00:00 2001 From: Imamah-Zafar <88320460+Imamah-Zafar@users.noreply.github.com> Date: Mon, 14 Nov 2022 15:47:28 +0500 Subject: [PATCH 2/4] remove console.log --- api/stacks.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/api/stacks.ts b/api/stacks.ts index f445e707..e2fe1e8d 100644 --- a/api/stacks.ts +++ b/api/stacks.ts @@ -396,15 +396,11 @@ export async function getBnsName(stxAddress: string, network: SettingsNetwork,) export async function getStacksInfo(network:string){ const url = `${network}/v2/info`; - console.log("inisde") - console.log(network) return axios .get(url, { timeout: 30000, }) .then((response) => { - console.log("response ") - console.log(response) return response?.data; }) .catch((error) => { From 00d66164744e5b3d8e19fe88647684584772791b Mon Sep 17 00:00:00 2001 From: Imamah-Zafar <88320460+Imamah-Zafar@users.noreply.github.com> Date: Tue, 15 Nov 2022 11:36:53 +0500 Subject: [PATCH 3/4] add utils for stacking screen --- api/stacks.ts | 61 ++++++++++++++++++++++++++-- api/xverse.ts | 24 +++++++++++ package-lock.json | 16 +++----- stacking/index.ts | 10 +++++ tsconfig.json | 4 +- types/api/stacks/assets.ts | 13 ++++++ types/api/xverse/stacking.ts | 78 ++++++++++++++++++++++++++++++++++++ types/index.ts | 8 ++++ 8 files changed, 200 insertions(+), 14 deletions(-) create mode 100644 stacking/index.ts create mode 100644 types/api/xverse/stacking.ts diff --git a/api/stacks.ts b/api/stacks.ts index e2fe1e8d..d36abd99 100644 --- a/api/stacks.ts +++ b/api/stacks.ts @@ -32,9 +32,9 @@ import { parseStxTransactionData, } from './helper'; import {StacksMainnet, StacksTestnet} from '@stacks/network'; -import { AnchorMode, estimateTransfer, makeUnsignedSTXTokenTransfer, UnsignedTokenTransferOptions, } from '@stacks/transactions'; +import { AnchorMode, ClarityType, cvToHex, cvToString, estimateTransfer, hexToCV, makeUnsignedSTXTokenTransfer, PrincipalCV, SomeCV, standardPrincipalCV, TupleCV, tupleCV, UIntCV, UnsignedTokenTransferOptions, } from '@stacks/transactions'; import { getNonce, setNonce } from '../transactions'; -import { AddressToBnsResponse, PoxData } from '../types/api/stacks/assets'; +import { AddressToBnsResponse, CoreInfo, DelegationInfo } from '../types/api/stacks/assets'; export async function getTransaction(txid: string, network: SettingsNetwork): Promise { return fetch(`${network.address}/extended/v1/tx/${txid}`, { @@ -397,7 +397,7 @@ export async function getBnsName(stxAddress: string, network: SettingsNetwork,) export async function getStacksInfo(network:string){ const url = `${network}/v2/info`; return axios - .get(url, { + .get(url, { timeout: 30000, }) .then((response) => { @@ -408,3 +408,58 @@ export async function getStacksInfo(network:string){ }); } + +export async function fetchDelegationState( + stxAddress: string, + network: SettingsNetwork, +): Promise { + const poxContractAddress = 'SP000000000000000000002Q6VF78'; + const poxContractName = 'pox'; + const mapName = 'delegation-state'; + const mapEntryPath = `/${poxContractAddress}/${poxContractName}/${mapName}`; + const apiUrl = `${network.address}/v2/map_entry${mapEntryPath}?proof=0`; + const key = cvToHex(tupleCV({stacker: standardPrincipalCV(stxAddress)})); + + return fetch(apiUrl, { + method: 'POST', + body: JSON.stringify(key), + headers: {'Content-Type': 'application/json'}, + }) + .then((response) => response.json()) + .then((response) => { + const responseCV = hexToCV(response['data']); + + if (responseCV.type === ClarityType.OptionalNone) { + return { + delegated: false, + }; + } else { + const someCV = responseCV as SomeCV; + const tupleCV = someCV.value as TupleCV; + const amount: UIntCV = tupleCV.data['amount-ustx'] as UIntCV; + const delegatedTo: PrincipalCV = tupleCV.data[ + 'delegated-to' + ] as PrincipalCV; + const untilBurnHeightSomeCV: SomeCV = tupleCV.data[ + 'until-burn-ht' + ] as SomeCV; + var untilBurnHeight = 9999999; + if (untilBurnHeightSomeCV.type === ClarityType.OptionalSome) { + const untilBurnHeightUIntCV: UIntCV = + untilBurnHeightSomeCV.value as UIntCV; + untilBurnHeight = Number(untilBurnHeightUIntCV.value); + } + const delegatedAmount = new BigNumber(amount.value.toString()); + + const delegationInfo = { + delegated: true, + amount: delegatedAmount.toString(), + delegatedTo: cvToString(delegatedTo), + untilBurnHeight: untilBurnHeight, + }; + + return delegationInfo; + } + }); +} + diff --git a/api/xverse.ts b/api/xverse.ts index a8737b7f..2005c1dd 100644 --- a/api/xverse.ts +++ b/api/xverse.ts @@ -7,6 +7,8 @@ import { SupportedCurrency, CoinsResponse, FeesMultipliers, + StackingPoolInfo, + StackerInfo, } from 'types'; export async function fetchBtcFeeRate(): Promise { @@ -82,3 +84,25 @@ export async function fetchAppInfo(): Promise { return null; }); } + +export async function fetchStackingPoolInfo(): Promise { + return fetch(`${XVERSE_API_BASE_URL}/v1/pool/info`, { + method: 'GET', + }) + .then((response) => response.json()) + .then((response) => { + return response; + }); +} + +export async function fetchPoolStackerInfo( + stxAddress: string, +): Promise { + return fetch(`${XVERSE_API_BASE_URL}/v1/pool/${stxAddress}/status`, { + method: 'GET', + }) + .then((response) => response.json()) + .then((response) => { + return response; + }); +} diff --git a/package-lock.json b/package-lock.json index 952f6e02..31a5fddb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "@secretkeylabs/xverse-core", "version": "0.0.1", + "hasInstallScript": true, "license": "ISC", "dependencies": { "@stacks/encryption": "4.3.5", @@ -7640,8 +7641,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", - "dev": true, - "requires": {} + "dev": true }, "@webpack-cli/info": { "version": "1.5.0", @@ -7656,8 +7656,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", - "dev": true, - "requires": {} + "dev": true }, "@xtuc/ieee754": { "version": "1.2.0", @@ -7681,8 +7680,7 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true, - "requires": {} + "dev": true }, "ajv": { "version": "6.12.6", @@ -7700,8 +7698,7 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "requires": {} + "dev": true }, "ansi-escapes": { "version": "4.3.2", @@ -9352,8 +9349,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} + "dev": true }, "jest-regex-util": { "version": "29.2.0", diff --git a/stacking/index.ts b/stacking/index.ts new file mode 100644 index 00000000..25f081ce --- /dev/null +++ b/stacking/index.ts @@ -0,0 +1,10 @@ +export type StackingState = + | 'Loading' + | 'NotStacking' + | 'Pending' + | 'Delegated' + | 'Stacking' + | 'Completed' + | 'Revoked' + | 'Error'; + diff --git a/tsconfig.json b/tsconfig.json index c5a96b51..cd1a87a2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,9 @@ "types/*": ["./types"], "currency/*": ["./currency"], "transactions/*": ["./transactions"], - "wallet/*": ["./wallet"] + "wallet/*": ["./wallet"], + "stacking/*": ["./stacking"], + }, "declaration": true, "sourceMap": true, diff --git a/types/api/stacks/assets.ts b/types/api/stacks/assets.ts index 49dedde4..a04af860 100644 --- a/types/api/stacks/assets.ts +++ b/types/api/stacks/assets.ts @@ -70,3 +70,16 @@ export interface PoxData { total_liquid_supply_ustx: string; next_reward_cycle_in: number; } +export interface DelegationInfo { + delegated: boolean; + amount?: string; + delegatedTo?: string; + untilBurnHeight?: number; +} + +export interface CoreInfo { + burn_block_height: number; + stable_burn_block_height: number; + stacks_tip_height: number; + stacks_tip: string; +} \ No newline at end of file diff --git a/types/api/xverse/stacking.ts b/types/api/xverse/stacking.ts new file mode 100644 index 00000000..a830185d --- /dev/null +++ b/types/api/xverse/stacking.ts @@ -0,0 +1,78 @@ +import BigNumber from "bignumber.js"; +import { CoreInfo } from "../stacks/assets"; + +export interface Pool { + address: string; + contract: string; + contract_version: number; + reward_address: string; + starting_cycle: number; + cycle_duration: number; + available_cycle_durations: number[]; + minimum: string; + fee_percent: number; + estimated_yield: number; +} + +export interface StackingPoolInfo { + open: boolean; + enrollment_closing_blocks: number; + enrollment_open_blocks: number; + pools: Array; + pool_total: string; + pox: { + contract_id: string; + first_burnchain_block_height: number; + min_amount_ustx: string; + prepare_cycle_length: number; + rejection_fraction: number; + reward_cycle_id: number; + reward_cycle_length: number; + rejection_votes_left_required: string; + total_liquid_supply_ustx: string; + next_reward_cycle_in: number; + }; +} + +export interface StackerInfo { + stacked: boolean; + pool_total?: string; + amount: string; + reward_share_pct?: string; + first_reward_cycle: number; + lock_period: number; + pool_pox_address: string; + user_pox_address: string; + poolContractName?: string; +} + +export interface DelegationInfo { + delegated: boolean; + amount?: string; + delegatedTo?: string; + untilBurnHeight?: number; +} + +export interface CurrentPoolReward { + currentCyclePoolRewardInBtc: string; + currentCyclePoolRewardInCurrency: string; +} + +export interface StackingData { + poolInfo: StackingPoolInfo; + delegationInfo: DelegationInfo; + coreInfo: CoreInfo; + stackerInfo?: StackerInfo; + currentPoolReward?: CurrentPoolReward; +} + +export interface StackingStateData { + delegated: boolean; + txid: string; + amount: BigNumber; + startingCycle: number; + duration: number; + poolContractAddress: string; + poolContractName: string; + revoked: boolean; + } diff --git a/types/index.ts b/types/index.ts index 893986c5..89db77c3 100644 --- a/types/index.ts +++ b/types/index.ts @@ -51,9 +51,11 @@ import { NftsListData, NonFungibleToken, NftEventsResponse, + CoreInfo, } from './api/stacks/assets'; import { NftDetailResponse } from './api/gamma/currency'; import { SupportedCurrency } from './currency'; +import { StackerInfo, StackingData, StackingPoolInfo, StackingStateData, Pool } from './api/xverse/stacking'; export { NetworkType, @@ -98,4 +100,10 @@ export { NftsListData, NonFungibleToken, NftEventsResponse, + StackingPoolInfo, + StackerInfo, + StackingData, + CoreInfo, + StackingStateData, + Pool }; From 66ed305625b4b3cda5fa1834df3529f41962c2d5 Mon Sep 17 00:00:00 2001 From: Imamah-Zafar <88320460+Imamah-Zafar@users.noreply.github.com> Date: Wed, 16 Nov 2022 15:13:14 +0500 Subject: [PATCH 4/4] use axios instead of fetch --- api/stacks.ts | 76 ++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 43 deletions(-) diff --git a/api/stacks.ts b/api/stacks.ts index d36abd99..64691310 100644 --- a/api/stacks.ts +++ b/api/stacks.ts @@ -411,55 +411,45 @@ export async function getStacksInfo(network:string){ export async function fetchDelegationState( stxAddress: string, - network: SettingsNetwork, + network: SettingsNetwork ): Promise { const poxContractAddress = 'SP000000000000000000002Q6VF78'; const poxContractName = 'pox'; const mapName = 'delegation-state'; const mapEntryPath = `/${poxContractAddress}/${poxContractName}/${mapName}`; const apiUrl = `${network.address}/v2/map_entry${mapEntryPath}?proof=0`; - const key = cvToHex(tupleCV({stacker: standardPrincipalCV(stxAddress)})); - - return fetch(apiUrl, { - method: 'POST', - body: JSON.stringify(key), - headers: {'Content-Type': 'application/json'}, - }) - .then((response) => response.json()) - .then((response) => { - const responseCV = hexToCV(response['data']); - - if (responseCV.type === ClarityType.OptionalNone) { - return { - delegated: false, - }; - } else { - const someCV = responseCV as SomeCV; - const tupleCV = someCV.value as TupleCV; - const amount: UIntCV = tupleCV.data['amount-ustx'] as UIntCV; - const delegatedTo: PrincipalCV = tupleCV.data[ - 'delegated-to' - ] as PrincipalCV; - const untilBurnHeightSomeCV: SomeCV = tupleCV.data[ - 'until-burn-ht' - ] as SomeCV; - var untilBurnHeight = 9999999; - if (untilBurnHeightSomeCV.type === ClarityType.OptionalSome) { - const untilBurnHeightUIntCV: UIntCV = - untilBurnHeightSomeCV.value as UIntCV; - untilBurnHeight = Number(untilBurnHeightUIntCV.value); - } - const delegatedAmount = new BigNumber(amount.value.toString()); - - const delegationInfo = { - delegated: true, - amount: delegatedAmount.toString(), - delegatedTo: cvToString(delegatedTo), - untilBurnHeight: untilBurnHeight, - }; - - return delegationInfo; + const key = cvToHex(tupleCV({ stacker: standardPrincipalCV(stxAddress) })); + const headers = { + 'Content-Type': 'application/json', + }; + return axios.post(apiUrl, JSON.stringify(key), { headers: headers }).then((response) => { + const responseCV = hexToCV(response.data.data); + if (responseCV.type === ClarityType.OptionalNone) { + return { + delegated: false, + }; + } else { + const someCV = responseCV as SomeCV; + const tupleCV = someCV.value as TupleCV; + const amount: UIntCV = tupleCV.data['amount-ustx'] as UIntCV; + const delegatedTo: PrincipalCV = tupleCV.data['delegated-to'] as PrincipalCV; + const untilBurnHeightSomeCV: SomeCV = tupleCV.data['until-burn-ht'] as SomeCV; + var untilBurnHeight = 9999999; + if (untilBurnHeightSomeCV.type === ClarityType.OptionalSome) { + const untilBurnHeightUIntCV: UIntCV = untilBurnHeightSomeCV.value as UIntCV; + untilBurnHeight = Number(untilBurnHeightUIntCV.value); } - }); + const delegatedAmount = new BigNumber(amount.value.toString()); + + const delegationInfo = { + delegated: true, + amount: delegatedAmount.toString(), + delegatedTo: cvToString(delegatedTo), + untilBurnHeight: untilBurnHeight, + }; + + return delegationInfo; + } + }); }