Skip to content

Commit

Permalink
Merge pull request #156 from lidofinance/feature/si-1524-steth-on-opt…
Browse files Browse the repository at this point in the history
…imism-in-sdk

Steth on optimism in sdk
  • Loading branch information
Jeday committed Sep 18, 2024
2 parents 9a6a036 + 6a188bf commit 99db55f
Show file tree
Hide file tree
Showing 38 changed files with 1,813 additions and 287 deletions.
2 changes: 1 addition & 1 deletion examples/erlang-bridge/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
},
"dependencies": {
"@lidofinance/lido-ethereum-sdk": "workspace:*",
"viem": "^2.0.6"
"viem": "^2.21.9"
}
}
2 changes: 1 addition & 1 deletion examples/rewards/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"dependencies": {
"@lidofinance/lido-ethereum-sdk": "workspace:*",
"viem": "^2.0.6"
"viem": "^2.21.9"
},
"devDependencies": {
"rimraf": "^5.0.5",
Expand Down
2 changes: 1 addition & 1 deletion packages/lido-pulse/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"fastify": "^4.28.1",
"fastify-plugin": "^4.5.1",
"reflect-metadata": "^0.2.2",
"viem": "^2.0.6"
"viem": "^2.21.9"
},
"devDependencies": {
"@types/node": "^20.14.10",
Expand Down
14 changes: 12 additions & 2 deletions packages/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@
"default": "./dist/cjs/shares/index.js",
"types": "./dist/types/shares/index.d.ts"
},
"./l2": {
"import": "./dist/esm/l2/index.js",
"default": "./dist/cjs/l2/index.js",
"types": "./dist/types/l2/index.d.ts"
},
"./package.json": "./package.json"
},
"typesVersions": {
Expand Down Expand Up @@ -104,6 +109,9 @@
],
"shares": [
"./dist/types/shares/index.d.ts"
],
"l2": [
"./dist/types/l2/index.d.ts"
]
}
},
Expand Down Expand Up @@ -145,8 +153,10 @@
"dependencies": {
"@ethersproject/bytes": "^5.7.0",
"graphql": "^16.8.1",
"graphql-request": "^6.1.0",
"viem": "^2.0.6"
"graphql-request": "^6.1.0"
},
"peerDependencies": {
"viem": "^2.21"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
Expand Down
32 changes: 30 additions & 2 deletions packages/sdk/src/common/constants.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { type Address, type Chain } from 'viem';
import { goerli, mainnet, holesky, sepolia } from 'viem/chains';
import {
goerli,
mainnet,
holesky,
sepolia,
optimismSepolia,
} from 'viem/chains';

export enum CHAINS {
Goerli = 5,
Mainnet = 1,
Holesky = 17000,
Sepolia = 11155111,
OptimismSepolia = 11155420,
}

export const APPROX_BLOCKS_BY_DAY = 7600n;
Expand All @@ -15,19 +22,21 @@ export const SUPPORTED_CHAINS: CHAINS[] = [
CHAINS.Mainnet,
CHAINS.Holesky,
CHAINS.Sepolia,
CHAINS.OptimismSepolia,
];

export const SUBMIT_EXTRA_GAS_TRANSACTION_RATIO = 1.05;
export const GAS_TRANSACTION_RATIO_PRECISION = 10 ** 7;
export const ESTIMATE_ACCOUNT = '0x87c0e047F4e4D3e289A56a36570D4CB957A37Ef1';

export const LIDO_LOCATOR_BY_CHAIN: {
[key in CHAINS]: Address;
[key in CHAINS]: Address | null;
} = {
[CHAINS.Mainnet]: '0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb',
[CHAINS.Goerli]: '0x1eDf09b5023DC86737b59dE68a8130De878984f5',
[CHAINS.Holesky]: '0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8',
[CHAINS.Sepolia]: '0x8f6254332f69557A72b0DA2D5F0Bc07d4CA991E7',
[CHAINS.OptimismSepolia]: null,
};

export const SUBRGRAPH_ID_BY_CHAIN: {
Expand All @@ -37,6 +46,7 @@ export const SUBRGRAPH_ID_BY_CHAIN: {
[CHAINS.Goerli]: 'QmeDfGTuNbSoZ71zi3Ch4WNRbzALfiFPnJMYUFPinLiFNa',
[CHAINS.Holesky]: null,
[CHAINS.Sepolia]: null,
[CHAINS.OptimismSepolia]: null,
};

export const EARLIEST_TOKEN_REBASED_EVENT: {
Expand All @@ -46,6 +56,7 @@ export const EARLIEST_TOKEN_REBASED_EVENT: {
[CHAINS.Goerli]: 8712039n,
[CHAINS.Holesky]: 52174n,
[CHAINS.Sepolia]: 5434668n,
[CHAINS.OptimismSepolia]: 0n,
} as const;

export const LIDO_TOKENS = {
Expand Down Expand Up @@ -73,6 +84,21 @@ export const enum LIDO_CONTRACT_NAMES {
wsteth = 'wsteth',
}

export const enum LIDO_L2_CONTRACT_NAMES {
wsteth = 'wsteth',
steth = 'steth',
}

export const LIDO_L2_CONTRACT_ADDRESSES: Record<
number,
Record<LIDO_L2_CONTRACT_NAMES, Address>
> = {
[CHAINS.OptimismSepolia]: {
wsteth: '0x24B47cd3A74f1799b32B2de11073764Cb1bb318B',
steth: '0xf49d208b5c7b10415c7beafe9e656f2df9edfe3b',
},
} as const;

export const CONTRACTS_BY_TOKENS = {
[LIDO_TOKENS.steth]: LIDO_CONTRACT_NAMES.lido,
[LIDO_TOKENS.wsteth]: LIDO_CONTRACT_NAMES.wsteth,
Expand Down Expand Up @@ -110,11 +136,13 @@ export const VIEM_CHAINS: { [key in CHAINS]: Chain } = {
[CHAINS.Goerli]: goerli,
[CHAINS.Holesky]: holesky,
[CHAINS.Sepolia]: sepolia,
[CHAINS.OptimismSepolia]: optimismSepolia,
};

export const WQ_API_URLS: { [key in CHAINS]: string | null } = {
[CHAINS.Mainnet]: 'https://wq-api.lido.fi',
[CHAINS.Goerli]: 'https://wq-api.testnet.fi',
[CHAINS.Holesky]: 'https://wq-api-holesky.testnet.fi',
[CHAINS.Sepolia]: null,
[CHAINS.OptimismSepolia]: null,
};
2 changes: 1 addition & 1 deletion packages/sdk/src/core/abi/wq.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const wqAbi = [
export const wqWstethAddressAbi = [
{
inputs: [],
name: 'WSTETH',
Expand Down
53 changes: 36 additions & 17 deletions packages/sdk/src/core/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ import {
SUBRGRAPH_ID_BY_CHAIN,
APPROX_SECONDS_PER_BLOCK,
NOOP,
LIDO_L2_CONTRACT_NAMES,
LIDO_L2_CONTRACT_ADDRESSES,
} from '../common/constants.js';

import { LidoLocatorAbi } from './abi/lidoLocator.js';
import { wqAbi } from './abi/wq.js';
import { wqWstethAddressAbi } from './abi/wq.js';
import type {
LidoSDKCoreProps,
PermitSignature,
Expand All @@ -57,6 +59,7 @@ import type {
import { TransactionCallbackStage } from './types.js';
import { permitAbi } from './abi/permit.js';
import { LidoSDKCacheable } from '../common/class-primitives/cacheable.js';
import { readContract } from 'viem/actions';

export default class LidoSDKCore extends LidoSDKCacheable {
public static readonly INFINITY_DEADLINE_VALUE = maxUint256;
Expand Down Expand Up @@ -170,7 +173,13 @@ export default class LidoSDKCore extends LidoSDKCacheable {
@Logger('Contracts:')
@Cache(30 * 60 * 1000, ['chain.id'])
public contractAddressLidoLocator(): Address {
return LIDO_LOCATOR_BY_CHAIN[this.chain.id as CHAINS];
const locator = LIDO_LOCATOR_BY_CHAIN[this.chain.id as CHAINS];
invariant(
locator,
`Lido Ethereum Contacts are not supported on ${this.chain.name}(${this.chain.id})`,
ERROR_CODE.NOT_SUPPORTED,
);
return locator;
}

@Logger('Contracts:')
Expand All @@ -186,18 +195,6 @@ export default class LidoSDKCore extends LidoSDKCacheable {
});
}

@Logger('Contracts:')
@Cache(30 * 60 * 1000, ['chain.id'])
private getContractWQ(
address: Address,
): GetContractReturnType<typeof wqAbi, PublicClient> {
return getContract({
address,
abi: wqAbi,
client: this.rpcProvider,
});
}

// PERMIT
@Logger('Permit:')
public async signPermit(props: SignPermitProps): Promise<PermitSignature> {
Expand Down Expand Up @@ -360,7 +357,7 @@ export default class LidoSDKCore extends LidoSDKCacheable {
// eth_getCode returns hex string of bytecode at address
// for accounts it's "0x"
// for contract it's potentially very long hex (can't be safely&quickly parsed)
const result = await this.rpcProvider.getBytecode({ address: address });
const result = await this.rpcProvider.getCode({ address: address });
return result ? result !== '0x' : false;
}

Expand All @@ -377,15 +374,37 @@ export default class LidoSDKCore extends LidoSDKCacheable {
const lidoLocator = this.getContractLidoLocator();
if (contract === 'wsteth') {
const withdrawalQueue = await lidoLocator.read.withdrawalQueue();
const contract = this.getContractWQ(withdrawalQueue);
const wstethAddress = await contract.read.WSTETH();

const wstethAddress = await readContract(this.rpcProvider, {
abi: wqWstethAddressAbi,
address: withdrawalQueue,
functionName: 'WSTETH',
});

return wstethAddress;
} else {
return lidoLocator.read[contract]();
}
}

@Logger('Utils:')
@Cache(30 * 60 * 1000, ['chain.id'])
public getL2ContractAddress(contract: LIDO_L2_CONTRACT_NAMES): Address {
const chainConfig = LIDO_L2_CONTRACT_ADDRESSES[this.chain.id];
invariant(
chainConfig,
`Lido L2 contracts are not supported for ${this.chain.name}(${this.chain.id})`,
ERROR_CODE.NOT_SUPPORTED,
);
const address = chainConfig[contract];
invariant(
address,
`Lido L2 on ${this.chain.name}(${this.chain.id}) does not have ${contract} contract`,
ERROR_CODE.NOT_SUPPORTED,
);
return address;
}

@Logger('Utils:')
@Cache(30 * 60 * 1000, ['chain.id'])
public getSubgraphId(): string | null {
Expand Down
82 changes: 51 additions & 31 deletions packages/sdk/src/erc20/erc20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ export abstract class AbstractLidoSDKErc20 extends LidoSDKModule {

const contract = await this.getContract();
return isTransferFrom
? contract.simulate.transferFrom([from, to, amount], { account })
? contract.simulate.transferFrom([from, to, amount], {
account,
})
: contract.simulate.transfer([to, amount], { account });
}

Expand Down Expand Up @@ -217,7 +219,9 @@ export abstract class AbstractLidoSDKErc20 extends LidoSDKModule {
public async simulateApprove(props: NoCallback<ApproveProps>) {
const { account, amount, to } = await this.parseProps(props);
const contract = await this.getContract();
return contract.simulate.approve([to, amount], { account });
return contract.simulate.approve([to, amount], {
account,
});
}

@Logger('Views:')
Expand All @@ -239,35 +243,51 @@ export abstract class AbstractLidoSDKErc20 extends LidoSDKModule {
decimals: number;
domainSeparator: Hash;
}> {
const contract = { address: await this.contractAddress(), abi: erc20abi };
const [decimals, name, symbol, domainSeparator] =
await this.core.rpcProvider.multicall({
allowFailure: false,
contracts: [
{
...contract,
functionName: 'decimals',
},
{
...contract,
functionName: 'name',
},
{
...contract,
functionName: 'symbol',
},
{
...contract,
functionName: 'DOMAIN_SEPARATOR',
},
] as const,
});
return {
decimals,
name,
symbol,
domainSeparator,
};
if (this.core.rpcProvider.multicall) {
const contract = { address: await this.contractAddress(), abi: erc20abi };
const [decimals, name, symbol, domainSeparator] =
await this.core.rpcProvider.multicall({
allowFailure: false,
contracts: [
{
...contract,
functionName: 'decimals',
},
{
...contract,
functionName: 'name',
},
{
...contract,
functionName: 'symbol',
},
{
...contract,
functionName: 'DOMAIN_SEPARATOR',
},
] as const,
});
return {
decimals,
name,
symbol,
domainSeparator,
};
} else {
const contract = await this.getContract();
const [decimals, name, symbol, domainSeparator] = await Promise.all([
contract.read.decimals(),
contract.read.name(),
contract.read.symbol(),
contract.read.DOMAIN_SEPARATOR(),
]);
return {
decimals,
name,
symbol,
domainSeparator,
};
}
}

@Logger('Views:')
Expand Down
1 change: 1 addition & 0 deletions packages/sdk/src/erc20/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { erc20abi } from './abi/erc20abi.js';
export { AbstractLidoSDKErc20 } from './erc20.js';
export { LidoSDKstETH } from './steth.js';
export { LidoSDKwstETH } from './wsteth.js';
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/src/erc20/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
export type InnerTransactionProps = Required<CommonTransactionProps>;

export type ParsedTransactionProps<TProps extends CommonTransactionProps> =
Omit<TProps, 'callback'> & {
Omit<TProps, 'callback' | 'account'> & {
callback: NonNullable<TProps['callback']>;
account: JsonRpcAccount;
} & (TProps extends { amount: EtherValue } ? { amount: bigint } : object);
Expand Down
2 changes: 2 additions & 0 deletions packages/sdk/src/erc20/wsteth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export class LidoSDKwstETH extends AbstractLidoSDKErc20 {
return this.core.getContractAddress(LIDO_CONTRACT_NAMES.wsteth);
}

@Logger('Contracts:')
@Cache(30 * 60 * 1000, ['core.chain.id'])
public override async erc721Domain(): Promise<{
name: string;
version: string;
Expand Down
1 change: 1 addition & 0 deletions packages/sdk/src/events/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { StethEventsAbi } from './abi/stethEvents.js';
export { LidoSDKEvents } from './events.js';
export * from './types.js';
Loading

0 comments on commit 99db55f

Please sign in to comment.