-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add abstracted contract interface to hyperdive/sdk (#355)
- Loading branch information
Showing
4 changed files
with
176 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
import { | ||
Abi, | ||
AbiParametersToPrimitiveTypes, | ||
ExtractAbiFunction, | ||
ExtractAbiFunctionNames, | ||
AbiStateMutability, | ||
ExtractAbiEventNames, | ||
ExtractAbiEvent, | ||
} from "abitype"; | ||
type EventName<TAbi extends Abi> = ExtractAbiEventNames<TAbi>; | ||
|
||
/** | ||
* Get a union of function names from an abi | ||
*/ | ||
export type FunctionName< | ||
TAbi extends Abi, | ||
TAbiStateMutability extends AbiStateMutability = AbiStateMutability, | ||
> = ExtractAbiFunctionNames<TAbi, TAbiStateMutability>; | ||
|
||
/** | ||
* Get an array of argument types for a function from an abi | ||
*/ | ||
export type FunctionArgs< | ||
TAbi extends Abi, | ||
TFunctionName extends FunctionName<TAbi> = FunctionName<TAbi>, | ||
> = AbiParametersToPrimitiveTypes< | ||
ExtractAbiFunction<TAbi, TFunctionName>["inputs"], | ||
"inputs" | ||
>; | ||
|
||
/** | ||
* Get the return type of a function from an abi | ||
*/ | ||
export type FunctionReturnType< | ||
TAbi extends Abi, | ||
TFunctionName extends FunctionName<TAbi> = FunctionName<TAbi>, | ||
> = AbiParametersToPrimitiveTypes< | ||
ExtractAbiFunction<TAbi, TFunctionName>["outputs"], | ||
"outputs" | ||
>[0]; | ||
|
||
/** | ||
* Get a strongly typed function type from an abi | ||
*/ | ||
export type ContractFunction< | ||
TAbi extends Abi, | ||
TAbiStateMutability extends AbiStateMutability = AbiStateMutability, | ||
> = <TFunctionName extends FunctionName<TAbi, TAbiStateMutability>>( | ||
fn: TFunctionName, | ||
args: FunctionArgs<TAbi, TFunctionName>, | ||
) => Promise<FunctionReturnType<TAbi, TFunctionName>>; | ||
|
||
/** | ||
* FilterArray<['a', 'b', 'c'], 'b'> = ['a', 'c'] | ||
*/ | ||
type FilterArray<T extends readonly any[], V> = T extends readonly [ | ||
infer L, | ||
...infer R, | ||
] | ||
? L extends V | ||
? [L, ...FilterArray<R, V>] | ||
: [...FilterArray<R, V>] | ||
: []; | ||
|
||
/** | ||
* Events in a contract abi look like this. There's obviously more fields, but | ||
* these are the ones we care about. | ||
*/ | ||
type AbiEventObject = { type: "address" | "uint256" }; | ||
|
||
/** | ||
* A mapping of event abi "type" field values to their typescript equivalents. | ||
*/ | ||
type TransformEventTypeMap = { | ||
address: string; | ||
uint256: bigint; | ||
}; | ||
|
||
/** | ||
* The resulting tuple of args values returned in an event from queryFilter. | ||
*/ | ||
type TransformEventTypes<Tup extends readonly AbiEventObject[]> = | ||
Tup extends readonly [ | ||
infer H extends AbiEventObject, | ||
...infer R extends readonly AbiEventObject[], | ||
] | ||
? [TransformEventTypeMap[H["type"]], ...TransformEventTypes<R>] | ||
: Tup; | ||
|
||
/** | ||
* A strongly typed Event you can expect back from calling queryFilter. | ||
* eg: TypedEvent<erc20ABI, 'Transfer'> = | ||
* { args: [from: string, to: string, amount: number]} | ||
*/ | ||
|
||
export interface TypedEvent< | ||
TAbi extends Abi, | ||
TEventName extends ExtractAbiEventNames<TAbi>, | ||
> extends Event { | ||
args: TransformEventTypes< | ||
FilterArray< | ||
ExtractAbiEvent<TAbi, TEventName>["inputs"], | ||
{ indexed: true } | { indexed: false } | ||
> | ||
>; | ||
} | ||
|
||
/** | ||
* A mapping of event abi "type" field values to their typescript equivalents. | ||
* This is for the filterArgs passed to queryFilter, so each one can also be | ||
* null. | ||
*/ | ||
type TransformFilterTypeMap = { | ||
address: string | null; | ||
uint256: bigint | null; | ||
}; | ||
|
||
/** | ||
* Identical to TransformEventTypes, however the resulting tuple will have null | ||
* as an option for each value. These are the accepted filterArgs values when | ||
* using queryFilter | ||
*/ | ||
type TransformFilterTypes<Tup extends readonly AbiEventObject[]> = | ||
Tup extends readonly [ | ||
infer H extends AbiEventObject, | ||
...infer R extends readonly AbiEventObject[], | ||
] | ||
? [TransformFilterTypeMap[H["type"]], ...TransformFilterTypes<R>] | ||
: Tup; | ||
|
||
/** | ||
* The filterArgs tuple containing all possible indexed fields you can use with | ||
* queryFilter, eg: | ||
* | ||
* ExtractEventFilterArgs<erc20ABI, 'Transfer'> = | ||
* [from: string | null, to: string | null] | ||
*/ | ||
export type EventFilter< | ||
TAbi extends Abi, | ||
TEventName extends ExtractAbiEventNames<TAbi>, | ||
> = TransformFilterTypes< | ||
FilterArray<ExtractAbiEvent<TAbi, TEventName>["inputs"], { indexed: true }> | ||
>; | ||
|
||
type BlockTag = "latest" | "earliest" | "pending" | "safe" | "finalized"; | ||
|
||
export type ContractEventFunction<TAbi extends Abi> = < | ||
TEventName extends EventName<TAbi>, | ||
>( | ||
eventName: TEventName, | ||
fromBlock: bigint | BlockTag, | ||
toBlock: bigint | BlockTag, | ||
filter: EventFilter<TAbi, TEventName>, | ||
) => Promise<TypedEvent<TAbi, TEventName>[]>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Abi, Address } from "abitype"; | ||
import { ContractEventFunction, ContractFunction } from "src/base/abitype"; | ||
|
||
/** | ||
* An abstracted contract interface to allow interchangeable web3 libraries. | ||
* Designed to be used by consumers that care about the interface of a contract, | ||
* but aren't necessarily concerned with where it's deployed or how it connects. | ||
*/ | ||
export interface Contract<TAbi extends Abi> { | ||
abi: TAbi; | ||
address: Address; | ||
read: ContractFunction<TAbi>; | ||
write: ContractFunction<TAbi, "nonpayable" | "payable">; | ||
getEvents: ContractEventFunction<TAbi>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3335,6 +3335,11 @@ [email protected]: | |
resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.9.3.tgz#294d25288ee683d72baf4e1fed757034e3c8c277" | ||
integrity sha512-dz4qCQLurx97FQhnb/EIYTk/ldQ+oafEDUqC0VVIeQS1Q48/YWt/9YNfMmp9SLFqN41ktxny3c8aYxHjmFIB/w== | ||
|
||
abitype@^0.9.8: | ||
version "0.9.8" | ||
resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.9.8.tgz#1f120b6b717459deafd213dfbf3a3dd1bf10ae8c" | ||
integrity sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ== | ||
|
||
abortcontroller-polyfill@^1.1.9: | ||
version "1.7.5" | ||
resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz#6738495f4e901fbb57b6c0611d0c75f76c485bed" | ||
|
@@ -10064,12 +10069,7 @@ [email protected]: | |
dependencies: | ||
is-typedarray "^1.0.0" | ||
|
||
typescript@^4.7.4, typescript@^4.9.3: | ||
version "4.9.5" | ||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" | ||
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== | ||
|
||
typescript@^5.0.2: | ||
typescript@^4.7.4, typescript@^4.9.3, typescript@^5.0.2: | ||
version "5.1.6" | ||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" | ||
integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== | ||
|
e5f24a5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
hyperdrive-monorepo-hyperdrive-trading – ./apps/hyperdrive-trading
hyperdrive-monorepo-hyperdrive-trading-delvtech.vercel.app
hyperdrive-monorepo-hyperdrive-trading-git-main-delvtech.vercel.app
hyperdrive-monorepo-hyperdrive-trading.vercel.app
e5f24a5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
hyperdrive-sdk-docs – ./apps/hyperdrive-sdk-docs
hyperdrive-sdk-docs-delvtech.vercel.app
hyperdrive-sdk-docs.vercel.app
hyperdrive-sdk-docs-git-main-delvtech.vercel.app
e5f24a5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
hyperdrive-fixed-borrow – ./apps/fixed-borrow
hyperdrive-fixed-borrow-git-main-delvtech.vercel.app
hyperdrive-fixed-borrow-delvtech.vercel.app
hyperdrive-fixed-borrow.vercel.app