feat: add ability to get user balances directly from SDK

This commit is contained in:
Kyle Fang
2023-04-28 21:46:03 +08:00
parent 4f11efc95f
commit 2b643d6cbf
5 changed files with 115 additions and 58 deletions

View File

@@ -52,9 +52,10 @@
"@stacks/transactions": "*"
},
"devDependencies": {
"@stacks/network": "^6.3.0",
"@stacks/transactions": "^6.2.0",
"@size-limit/preset-small-lib": "^8.2.4",
"@stacks/network": "^6.3.0",
"@stacks/stacks-blockchain-api-types": "^7.1.7",
"@stacks/transactions": "^6.2.0",
"esm": "^3.2.25",
"husky": "^8.0.3",
"prettier": "^2.8.4",

6
pnpm-lock.yaml generated
View File

@@ -3,6 +3,7 @@ lockfileVersion: 5.4
specifiers:
'@size-limit/preset-small-lib': ^8.2.4
'@stacks/network': ^6.3.0
'@stacks/stacks-blockchain-api-types': ^7.1.7
'@stacks/transactions': ^6.2.0
clarity-codegen: ^0.2.0
esm: ^3.2.25
@@ -19,6 +20,7 @@ dependencies:
devDependencies:
'@size-limit/preset-small-lib': 8.2.4_size-limit@8.2.4
'@stacks/network': 6.3.0
'@stacks/stacks-blockchain-api-types': 7.1.7
'@stacks/transactions': 6.5.0
esm: 3.2.25
husky: 8.0.3
@@ -1824,6 +1826,10 @@ packages:
resolution: {integrity: sha512-8vL+bPLTK0Sio3aJyIYITmdkwCCj01C5MqOQisC/GwthQvqf53uceAIsSsSQmVpFwvL5rqG0KGAu4rosW7QUwQ==}
dev: false
/@stacks/stacks-blockchain-api-types/7.1.7:
resolution: {integrity: sha512-6up6n3+qGYOwJ12bp+trsm0/npE7+ovSig+lFw6aboWCor/e0dO+fDXhJMQIrGJHHY0gw5OKeEsCcRCDwY4SYw==}
dev: true
/@stacks/transactions/6.5.0:
resolution: {integrity: sha512-kwE8cZq+QdAum4/LC+lSlAXVvzkdsSHTkCbfg4+VCWPBqA+gdXEqZe6R9SNBtMb8yGQrqUY8uIGRLVCWcXJ8zQ==}
dependencies:

View File

@@ -4,7 +4,10 @@ import { AMMSwapPool } from './utils/ammPool';
import { getRoute } from './helpers/RouteHelper';
import { getYAmountFromXAmount } from './helpers/RateHelper';
import { runSpot, TxToBroadCast } from './helpers/SwapHelper';
import { findCurrencyByNativeAddress } from './utils/currencyUtils';
import {
fetchBalanceForAccount,
findCurrencyByNativeAddress,
} from './utils/currencyUtils';
import { fetchLatestPrices } from './utils/currencyPrice';
import { AlexConfig, assignConfig } from './config';
@@ -13,6 +16,10 @@ export class AlexSDK {
assignConfig(config);
}
getBalances(stxAddress: string): Promise<{ [currency in Currency]: bigint }> {
return fetchBalanceForAccount(stxAddress);
}
getFeeRate(from: Currency, to: Currency): Promise<bigint> {
return getLiquidityProviderFee(from, to, AMMSwapPool.ammTokens);
}

View File

@@ -1,15 +1,84 @@
import { Currency } from './currency';
const CONTRACT_DEPLOYER = 'SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9';
const API_HOST = 'https://stacks-blockchain-lb.alexlab.co';
const IS_MAINNET = true;
const NATIVE_TOKEN_MAPPING = {
'age000-governance-token': {
assetIdentifier:
'SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.age000-governance-token::alex',
decimals: 1e8,
},
'token-wxusd': {
assetIdentifier:
'SP2TZK01NKDC89J6TA56SA47SDF7RTHYEQ79AAB9A.Wrapped-USD::wrapped-usd',
decimals: 1e8,
},
'token-wbtc': {
assetIdentifier:
'SP3DX3H4FEYZJZ586MFBS25ZW3HZDMEW92260R2PR.Wrapped-Bitcoin::wrapped-bitcoin',
decimals: 1e8,
},
'token-wdiko': {
assetIdentifier:
'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.arkadiko-token::diko',
decimals: 1e6,
},
'token-wusda': {
assetIdentifier:
'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.usda-token::usda',
decimals: 1e6,
},
'token-wban': {
assetIdentifier:
'SP2KAF9RF86PVX3NEE27DFV1CQX0T4WGR41X3S45C.btc-monkeys-bananas::BANANA',
decimals: 1e6,
},
'token-wslm': {
assetIdentifier:
'SP125J1ADVYWGWB9NQRCVGKYAG73R17ZNMV17XEJ7.slime-token::SLIME',
decimals: 1e6,
},
'token-wmia': {
assetIdentifier:
'SP1H1733V5MZ3SZ9XRW9FKYGEZT0JDGEB8Y634C7R.miamicoin-token-v2::miamicoin',
decimals: 1e6,
},
'token-wnycc': {
assetIdentifier:
'SPSCWDV3RKV5ZRN1FQD84YE1NQFEDJ9R1F4DYQ11.newyorkcitycoin-token-v2::newyorkcitycoin',
decimals: 1e6,
},
'token-wcorgi': {
decimals: 1e6,
assetIdentifier: `SP3NE50GEXFG9SZGTT51P40X2CKYSZ5CC4ZTZ7A2G.welshcorgicoin-token::welshcorgicoin`,
},
} as {
[P in Exclude<Currency, Currency.STX>]: {
decimals: number;
assetIdentifier: string;
};
};
export const configs = {
IS_MAINNET,
CONTRACT_DEPLOYER,
API_HOST,
NATIVE_TOKEN_MAPPING,
};
export type AlexConfig = typeof configs;
export function assignConfig(newConfigs: Partial<AlexConfig>) {
Object.assign(configs, newConfigs);
export function assignConfig(
newConfigs: Partial<AlexConfig> & {
NATIVE_TOKEN_MAPPING: Partial<AlexConfig['NATIVE_TOKEN_MAPPING']>;
}
) {
Object.assign(configs, newConfigs, {
NATIVE_TOKEN_MAPPING: {
...NATIVE_TOKEN_MAPPING,
...newConfigs.NATIVE_TOKEN_MAPPING,
},
});
}

View File

@@ -1,68 +1,19 @@
import { Currency } from '../currency';
const tokenNativeAddressDefinition = {
'age000-governance-token':
'SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.age000-governance-token::alex',
'token-wxusd':
'SP2TZK01NKDC89J6TA56SA47SDF7RTHYEQ79AAB9A.Wrapped-USD::wrapped-usd',
'token-wbtc':
'SP3DX3H4FEYZJZ586MFBS25ZW3HZDMEW92260R2PR.Wrapped-Bitcoin::wrapped-bitcoin',
'token-wdiko': {
assetIdentifier:
'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.arkadiko-token::diko',
decimals: 1e6,
},
'token-wusda': {
assetIdentifier:
'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.usda-token::usda',
decimals: 1e6,
},
'token-wban': {
assetIdentifier:
'SP2KAF9RF86PVX3NEE27DFV1CQX0T4WGR41X3S45C.btc-monkeys-bananas::BANANA',
decimals: 1e6,
},
'token-wslm': {
assetIdentifier:
'SP125J1ADVYWGWB9NQRCVGKYAG73R17ZNMV17XEJ7.slime-token::SLIME',
decimals: 1e6,
},
'token-wmia': {
assetIdentifier:
'SP1H1733V5MZ3SZ9XRW9FKYGEZT0JDGEB8Y634C7R.miamicoin-token-v2::miamicoin',
decimals: 1e6,
},
'token-wnycc': {
assetIdentifier:
'SPSCWDV3RKV5ZRN1FQD84YE1NQFEDJ9R1F4DYQ11.newyorkcitycoin-token-v2::newyorkcitycoin',
decimals: 1e6,
},
'token-wcorgi': {
decimals: 1e6,
assetIdentifier: `SP3NE50GEXFG9SZGTT51P40X2CKYSZ5CC4ZTZ7A2G.welshcorgicoin-token::welshcorgicoin`,
},
};
import { configs } from '../config';
import type { AddressBalanceResponse } from '@stacks/stacks-blockchain-api-types';
export function getCurrencyNativeScale(currency: Currency) {
if (currency === Currency.STX) {
return 1e6;
}
const address = tokenNativeAddressDefinition[currency];
if (typeof address === 'string') {
return 1e8;
}
return address.decimals;
return configs.NATIVE_TOKEN_MAPPING[currency].decimals;
}
export function getCurrencyNativeAddress(currency: Currency) {
if (currency === Currency.STX) {
throw new Error('STX is not a token');
}
const address = tokenNativeAddressDefinition[currency];
if (typeof address === 'string') {
return address;
}
return address.assetIdentifier;
return configs.NATIVE_TOKEN_MAPPING[currency].assetIdentifier;
}
export function findCurrencyByNativeAddress(
@@ -75,3 +26,26 @@ export function findCurrencyByNativeAddress(
getCurrencyNativeAddress(a).split('::')[0] === address.split('::')[0]
);
}
export async function fetchBalanceForAccount(
stxAddress: string
): Promise<{ [currency in Currency]: bigint }> {
const response: AddressBalanceResponse = await fetch(
`${configs.API_HOST}/extended/v1/address/${stxAddress}/balances`
).then((a) => a.json());
const allCurrencies = Object.values(Currency);
const balances = allCurrencies.map((a) => {
if (a === Currency.STX) return BigInt(response.stx.balance) * BigInt(100);
const fungibleToken =
response.fungible_tokens[getCurrencyNativeAddress(a)]?.balance;
if (fungibleToken == null) {
return BigInt(0);
}
return (
(BigInt(fungibleToken) * BigInt(1e8)) / BigInt(getCurrencyNativeScale(a))
);
});
return Object.fromEntries(
allCurrencies.map((a, i) => [a, balances[i]])
) as any;
}