Skip to content

Commit

Permalink
updated multi currency support
Browse files Browse the repository at this point in the history
  • Loading branch information
H34D committed Mar 23, 2023
1 parent 6818a06 commit b75089c
Show file tree
Hide file tree
Showing 17 changed files with 154 additions and 159 deletions.
8 changes: 3 additions & 5 deletions src/account/account.ts
@@ -1,8 +1,6 @@
import { getBalances } from "./get-balances";
import Masa from "../masa";
import { MasaBase } from "../helpers/masa-base";

export class MasaAccount {
constructor(private mass: Masa) {}

getBalances = (address?: string) => getBalances(this.mass, address);
export class MasaAccount extends MasaBase {
getBalances = (address?: string) => getBalances(this.masa, address);
}
162 changes: 78 additions & 84 deletions src/account/get-balances.ts
@@ -1,4 +1,4 @@
import { addresses } from "../contracts";
import { addresses, PaymentMethod } from "../contracts";
import {
IERC20__factory,
SoulboundCreditScore,
Expand All @@ -9,39 +9,37 @@ import {
import Masa from "../masa";
import { BigNumber, constants } from "ethers";

type BalanceTypes = "Native" | PaymentMethod | SBTContractNames;

export type Balances = {
[index in BalanceTypes]?: BigNumber;
};

type SBTContractNames = "Identity" | "SoulName" | "Green" | "CreditScore";

type SBTContracts =
| SoulboundIdentity
| SoulName
| SoulboundCreditScore
| SoulboundGreen;

export const getBalances = async (
masa: Masa,
address?: string
): Promise<
| {
ethBalance: BigNumber;
masaBalance: BigNumber;
usdcBalance: BigNumber;
wethBalance: BigNumber;
identityBalance: BigNumber;
soulNameBalance: BigNumber;
soulboundCreditScoreBalance: BigNumber;
soulboundGreenBalance: BigNumber;
}
| undefined
> => {
if (!masa.config.wallet.provider) return;

): Promise<Balances> => {
const contractAddresses = addresses[masa.config.network];
const addressToLoad = address || (await masa.config.wallet.getAddress());

const loadERC20Balance = async (
userAddress: string,
tokenAddress?: string
) => {
let result = BigNumber.from(0);

): Promise<BigNumber | undefined> => {
if (
!masa.config.wallet.provider ||
!tokenAddress ||
tokenAddress === constants.AddressZero
) {
return result;
return;
}

try {
Expand All @@ -50,92 +48,88 @@ export const getBalances = async (
masa.config.wallet.provider
);

result = await contract.balanceOf(userAddress);
return await contract.balanceOf(userAddress);
} catch (error: unknown) {
if (error instanceof Error) {
console.error(
`Token: ${tokenAddress} Wallet Address: ${addressToLoad} ${error.message}`
);
}
}

return result;
};

const loadContractBalance = async (
contract:
| SoulboundIdentity
| SoulName
| SoulboundCreditScore
| SoulboundGreen,
contract: SBTContracts,
addressToLoad: string
) => {
let result = BigNumber.from(0);
if (contract.address === constants.AddressZero) return result;
): Promise<BigNumber | undefined> => {
if (contract.address === constants.AddressZero) return;

try {
result = await contract.balanceOf(addressToLoad);
return await contract.balanceOf(addressToLoad);
} catch (error: unknown) {
if (error instanceof Error) {
console.error(
`Contract: ${contract.name} Wallet Address: ${addressToLoad} ${error.message}`
);
}
}

return result;
};

const [
ethBalance,
masaBalance,
usdcBalance,
wethBalance,
identityBalance,
soulNameBalance,
soulboundCreditScoreBalance,
soulboundGreenBalance,
] = await Promise.all([
// ETH
masa.config.wallet.provider.getBalance(addressToLoad),
// MASA
loadERC20Balance(addressToLoad, contractAddresses?.MASA),
// USDC
loadERC20Balance(addressToLoad, contractAddresses?.USDC),
// WETH
loadERC20Balance(addressToLoad, contractAddresses?.WETH),
// SBI
loadContractBalance(
masa.contracts.instances.SoulboundIdentityContract,
addressToLoad
),
// MSN
loadContractBalance(
masa.contracts.instances.SoulNameContract,
addressToLoad
),
// SCS
loadContractBalance(
masa.contracts.instances.SoulboundCreditScoreContract,
addressToLoad
),
// Green
loadContractBalance(
masa.contracts.instances.SoulboundGreenContract,
addressToLoad
),
]);

const balances = {
ethBalance,
masaBalance,
usdcBalance,
wethBalance,
identityBalance,
soulNameBalance,
soulboundCreditScoreBalance,
soulboundGreenBalance,
let ERC20Balances;

if (contractAddresses?.tokens) {
const paymentMethods = Object.keys(contractAddresses.tokens);
ERC20Balances = await paymentMethods.reduce(
async (
accumulatedBalances: Promise<Partial<Balances>>,
symbol: string
) => {
const balance = await loadERC20Balance(
addressToLoad,
contractAddresses?.tokens?.[symbol as PaymentMethod]
);

const accumulated = await accumulatedBalances;
return balance
? { ...accumulated, [symbol]: balance }
: { ...accumulated };
},
Promise.resolve({})
);
}

const Native: BigNumber | undefined =
await masa.config.wallet.provider?.getBalance(addressToLoad);

const SBTContractBalances: {
[key in SBTContractNames]: SBTContracts;
} = {
Identity: masa.contracts.instances.SoulboundIdentityContract,
SoulName: masa.contracts.instances.SoulNameContract,
CreditScore: masa.contracts.instances.SoulboundCreditScoreContract,
Green: masa.contracts.instances.SoulboundGreenContract,
};

return balances;
const SBTBalances = await Object.keys(SBTContractBalances).reduce(
async (accumulatedBalances: Promise<Partial<Balances>>, symbol: string) => {
const balance = await loadContractBalance(
SBTContractBalances[symbol as SBTContractNames],
addressToLoad
);
const accumulated = await accumulatedBalances;

return balance
? { ...accumulated, [symbol]: balance }
: { ...accumulated };
},
Promise.resolve({})
);

return {
Native,
// ERC20
...ERC20Balances,
// SBT
...SBTBalances,
};
};
23 changes: 20 additions & 3 deletions src/contracts/addresses.ts
Expand Up @@ -12,10 +12,27 @@ import {
} from "./networks";
import { NetworkName } from "../interface";

const erc20 = ["MASA", "WETH", "G$", "USDC", "cUSD"] as const;
export type ERC20 = (typeof erc20)[number];

const nativeCurrencies = ["ETH", "CELO"] as const;
export type NativeCurrencies = (typeof nativeCurrencies)[number];

export const isNativeCurrency = (
paymentMethod: unknown
): paymentMethod is NativeCurrencies =>
nativeCurrencies.includes(paymentMethod as NativeCurrencies);

export const isERC20Currency = (
paymentMethod: unknown
): paymentMethod is ERC20 => erc20.includes(paymentMethod as ERC20);

export type PaymentMethod = NativeCurrencies | ERC20;

export type Tokens = Partial<{ [key in PaymentMethod]: string }>;

export interface Addresses {
USDC?: string;
WETH?: string;
MASA?: string;
tokens?: Tokens;
SoulboundIdentityAddress?: string;
SoulboundCreditScoreAddress?: string;
SoulNameAddress?: string;
Expand Down

0 comments on commit b75089c

Please sign in to comment.