Skip to content
This repository was archived by the owner on Oct 28, 2025. It is now read-only.
Closed
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
397 changes: 0 additions & 397 deletions README.md

Large diffs are not rendered by default.

12 changes: 0 additions & 12 deletions hardhat.config.ts

This file was deleted.

22 changes: 9 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "@balmy/sdk",
"version": "0.9.0",
"name": "@nchamo/sdk",
"version": "0.0.1",
"contributors": [
{
"name": "Nicolás Chamo",
"email": "nchamo@balmy.xyz",
"name": "Nicolas Chamo",
"email": "nicolas@chamo.com.ar",
"url": "https://github.com/nchamo"
},
{
Expand Down Expand Up @@ -34,8 +34,7 @@
"prepare": "husky install",
"script": "ts-node -r tsconfig-paths/register",
"test": "jest --forceExit --detectOpenHandles --verbose",
"test:integration": "jest --forceExit --detectOpenHandles --verbose --testPathPattern=test/integration -t \"^(?!.*\\[External Quotes\\]).*$\"",
"test:integration:quotes": "jest --forceExit --detectOpenHandles --verbose -t \".*\\[External Quotes\\].*\"",
"test:integration": "jest --forceExit --detectOpenHandles --verbose --testPathPattern=test/integration",
"test:unit": "jest --forceExit --detectOpenHandles --verbose --testPathPattern=test/unit"
},
"lint-staged": {
Expand All @@ -49,24 +48,21 @@
"lru-cache": "9.0.3",
"ms": "3.0.0-canary.1",
"qs": "6.11.2",
"viem": "2.28.0"
"viem": "2.33.1"
},
"devDependencies": {
"@commitlint/cli": "17.8.0",
"@commitlint/config-conventional": "17.8.0",
"@nomicfoundation/hardhat-chai-matchers": "1.0.6",
"@nomicfoundation/hardhat-network-helpers": "1.0.8",
"@nomicfoundation/hardhat-toolbox": "2.0.2",
"@nomiclabs/hardhat-ethers": "2.2.3",
"@types/chai": "5.2.2",
"@types/chai-as-promised": "7",
"@types/crypto-js": "4.1.2",
"@types/jest": "29.5.6",
"@types/node": "18.16.3",
"@types/qs": "6.9.10",
"@types/ws": "8.5.10",
"chai": "4.3.7",
"chai-as-promised": "7",
"dotenv": "16.3.1",
"ethers": "5.7.2",
"hardhat": "2.23.0",
"husky": "8.0.3",
"jest": "29.7.0",
"lint-staged": "13.2.2",
Expand Down
9 changes: 7 additions & 2 deletions src/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ export const Chains = {
'https://polygon-mainnet.public.blastapi.io',
'https://rpc.ankr.com/polygon',
'https://rpc-mainnet.matic.quiknode.pro',
'https://matic-mainnet.chainstacklabs.com',
'https://polygon-pokt.nodies.app',
],
explorer: 'https://polygonscan.com/',
Expand Down Expand Up @@ -486,7 +485,13 @@ export const Chains = {
ids: ['scroll'],
nativeCurrency: { symbol: 'ETH', name: 'Ethereum' },
wToken: '0x5300000000000000000000000000000000000004',
publicRPCs: ['https://scroll-mainnet.chainstacklabs.com', 'https://rpc.ankr.com/scroll', 'https://rpc.scroll.io', 'https://1rpc.io/scroll'],
publicRPCs: [
'https://rpc.ankr.com/scroll',
'https://rpc.scroll.io',
'https://1rpc.io/scroll',
'https://scroll.therpc.io',
'https://scroll-rpc.publicnode.com',
],
explorer: 'https://scrollscan.com/',
},
MANTLE: {
Expand Down
28 changes: 0 additions & 28 deletions src/sdk/builders/dca-builder.ts

This file was deleted.

31 changes: 0 additions & 31 deletions src/sdk/builders/earn-builder.ts

This file was deleted.

8 changes: 0 additions & 8 deletions src/sdk/builders/permit2-builder.ts

This file was deleted.

18 changes: 0 additions & 18 deletions src/sdk/sdk-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ import { buildBalanceService, BuildBalancesParams } from './builders/balance-bui
import { buildAllowanceService, BuildAllowanceParams } from './builders/allowance-builder';
import { ISDK } from './types';
import { BuildPriceParams, buildPriceService } from './builders/price-builder';
import { buildPermit2Service } from './builders/permit2-builder';
import { BuildDCAParams, buildDCAService } from './builders/dca-builder';
import { BuildBlocksParams, buildBlocksService } from './builders/blocks-builder';
import { BuildEarnParams, buildEarnService } from './builders/earn-builder';

export function buildSDK<Params extends BuildParams = {}>(
params?: Params
Expand All @@ -26,16 +23,6 @@ export function buildSDK<Params extends BuildParams = {}>(
const metadataService = buildMetadataService<Params['metadata']>(params?.metadata, fetchService, providerService);
const priceService = buildPriceService(params?.price, fetchService);
const quoteService = buildQuoteService(params?.quotes, providerService, fetchService, gasService as any, metadataService as any, priceService);
const permit2Service = buildPermit2Service(quoteService, providerService, gasService as any);
const dcaService = buildDCAService(params?.dca, { providerService, permit2Service, quoteService, fetchService, priceService });
const earnService = buildEarnService(params?.earn, {
permit2Service,
quoteService,
providerService,
allowanceService,
fetchService,
balanceService,
});

return {
providerService,
Expand All @@ -47,9 +34,6 @@ export function buildSDK<Params extends BuildParams = {}>(
priceService,
quoteService,
logsService,
permit2Service,
dcaService,
earnService,
blocksService,
};
}
Expand All @@ -60,8 +44,6 @@ export type BuildParams = {
balances?: BuildBalancesParams;
allowances?: BuildAllowanceParams;
gas?: BuildGasParams;
dca?: BuildDCAParams;
earn?: BuildEarnParams;
metadata?: BuildMetadataParams;
price?: BuildPriceParams;
quotes?: BuildQuoteParams;
Expand Down
6 changes: 0 additions & 6 deletions src/sdk/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ import { IMetadataService } from '@services/metadata/types';
import { CalculateMetadataFromSourceParams } from './builders/metadata-builder';
import { CalculateGasValuesFromSourceParams } from './builders/gas-builder';
import { ILogsService } from '@services/logs';
import { IPermit2Service } from '@services/permit2';
import { IDCAService } from '@services/dca';
import { IBlocksService } from '@services/blocks';
import { IEarnService } from '@services/earn';

export type ISDK<
TokenMetadata extends object = CalculateMetadataFromSourceParams<undefined>,
Expand All @@ -27,8 +24,5 @@ export type ISDK<
priceService: IPriceService;
logsService: ILogsService;
metadataService: IMetadataService<TokenMetadata>;
permit2Service: IPermit2Service;
dcaService: IDCAService;
earnService: IEarnService;
blocksService: IBlocksService;
};
112 changes: 25 additions & 87 deletions src/services/balances/balance-sources/rpc-balance-source.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Hex, parseAbi, Address as ViemAddress } from 'viem';
import { parseAbi, Address as ViemAddress } from 'viem';
import { Address, ChainId, TimeString, TokenAddress } from '@types';
import { BalanceInput, IBalanceSource } from '../types';
import { IProviderService } from '@services/providers/types';
Expand Down Expand Up @@ -51,62 +51,31 @@ export class RPCBalanceSource implements IBalanceSource {
tokens: Omit<BalanceInput, 'chainId'>[],
config?: { timeout?: TimeString }
): Promise<Record<Address, Record<TokenAddress, bigint>>> {
const accountsToFetchNativeToken: Address[] = [];
const nonNativeTokens: Omit<BalanceInput, 'chainId'>[] = [];

for (const { account, token } of tokens) {
if (isSameAddress(token, Addresses.NATIVE_TOKEN)) {
accountsToFetchNativeToken.push(account);
} else {
nonNativeTokens.push({ account, token });
}
}

const erc20Promise =
Object.keys(nonNativeTokens).length > 0
? this.fetchERC20BalancesInChain(chainId, nonNativeTokens, config)
: Promise.resolve<Record<Address, Record<TokenAddress, bigint>>>({});

const nativePromise =
accountsToFetchNativeToken.length > 0
? this.fetchNativeBalancesInChain(chainId, accountsToFetchNativeToken, config)
: Promise.resolve<Record<Address, bigint>>({});
if (tokens.length === 0) return {};

const contracts = tokens.map(({ account, token }) =>
isSameAddress(token, Addresses.NATIVE_TOKEN)
? {
abi: MULTICALL_ABI,
functionName: 'getEthBalance' as const,
args: [account],
address: MULTICALL_CONTRACT.address(chainId),
}
: {
address: token as ViemAddress,
abi: ERC20_ABI,
functionName: 'balanceOf' as const,
args: [account],
}
);

const [erc20Result, nativeResult] = await Promise.all([erc20Promise, nativePromise]);
const multicallResults = await this.providerService.getViemPublicClient({ chainId }).multicall({
contracts,
multicallAddress: MULTICALL_CONTRACT.address(chainId),
batchSize: this.config?.batching?.maxSizeInBytes ?? 0,
});

const result: Record<Address, Record<TokenAddress, bigint>> = {};

for (const { account, token } of tokens) {
const balance = isSameAddress(token, Addresses.NATIVE_TOKEN) ? nativeResult[account] : erc20Result[account]?.[token];

if (balance !== undefined) {
if (!(account in result)) result[account] = {};
result[account][token] = balance;
}
}

return result;
}

private async fetchERC20BalancesInChain(
chainId: ChainId,
tokens: Omit<BalanceInput, 'chainId'>[],
config?: { timeout?: TimeString }
): Promise<Record<Address, Record<TokenAddress, bigint>>> {
const contracts = tokens.map(({ account, token }) => ({
address: token as ViemAddress,
abi: ERC20_ABI,
functionName: 'balanceOf',
args: [account],
}));
const multicallResults = contracts.length
? await this.providerService.getViemPublicClient({ chainId }).multicall({
contracts,
multicallAddress: MULTICALL_CONTRACT.address(chainId),
batchSize: this.config?.batching?.maxSizeInBytes ?? 0,
})
: [];
const result: Record<Address, Record<TokenAddress, bigint>> = {};
for (let i = 0; i < tokens.length; i++) {
const multicallResult = multicallResults[i];
if (multicallResult.status === 'failure') continue;
Expand All @@ -116,38 +85,7 @@ export class RPCBalanceSource implements IBalanceSource {
}
return result;
}

private async fetchNativeBalancesInChain(
chainId: ChainId,
accounts: Address[],
config?: { timeout?: TimeString }
): Promise<Record<Address, bigint>> {
if (accounts.length === 0) return {};

let balances: Readonly<bigint[]>;

try {
// We are using deployless reads to perform a sort of multicall and fetch all native balances in one call
balances = await this.providerService.getViemPublicClient({ chainId }).readContract({
code: BYTECODE,
abi: ABI,
functionName: 'getNativeBalances',
args: [accounts as ViemAddress[]],
blockTag: 'latest',
});
} catch {
// Some chains don't support deployless reads, so we fallback to fetching each balance individually
balances = await Promise.all(accounts.map((account) => this.fetchNativeBalanceInChain(chainId, account)));
}

return Object.fromEntries(accounts.map((account, i) => [account, balances[i]]));
}

private fetchNativeBalanceInChain(chainId: ChainId, account: Address, config?: { timeout?: TimeString }) {
return this.providerService.getViemPublicClient({ chainId }).getBalance({ address: account as ViemAddress, blockTag: 'latest' });
}
}

const BYTECODE: Hex =
'0x608060405234801561001057600080fd5b506102ed806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80634c04bf9914610030575b600080fd5b61004361003e3660046101cf565b610059565b604051610050919061023e565b60405180910390f35b60608167ffffffffffffffff81111561009b577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156100c4578160200160208202803683370190505b50905060005b8281101561018d5783838281811061010b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906101209190610194565b73ffffffffffffffffffffffffffffffffffffffff1631828281518110610170577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60209081029190910101528061018581610282565b9150506100ca565b5092915050565b6000602082840312156101a5578081fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146101c8578182fd5b9392505050565b600080602083850312156101e1578081fd5b823567ffffffffffffffff808211156101f8578283fd5b818501915085601f83011261020b578283fd5b813581811115610219578384fd5b866020808302850101111561022c578384fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b818110156102765783518352928401929184019160010161025a565b50909695505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156102d9577f4e487b710000000000000000000000000000000000000000000000000000000081526011600452602481fd5b506001019056fea164736f6c6343000800000a';
const ABI = parseAbi(['function getNativeBalances(address[] addresses) external view returns (uint256[] balances)']);
// The Multicall3 contract has this function that we can use to fetch all native balances in one call
const MULTICALL_ABI = parseAbi(['function getEthBalance(address addr) external view returns (uint256 balance)']);
15 changes: 0 additions & 15 deletions src/services/dca/config.ts

This file was deleted.

Loading
Loading