Skip to content

Commit 78927cf

Browse files
committed
Add notes and reformat design doc
1 parent 798f967 commit 78927cf

File tree

2 files changed

+170
-176
lines changed

2 files changed

+170
-176
lines changed

DESIGN.md

+49-176
Original file line numberDiff line numberDiff line change
@@ -1,205 +1,78 @@
1-
Design Document for Wormhole SDK
2-
---------------------------------
1+
# Design
32

4-
# Organization
3+
## Structure
54

6-
Code is organized into workspaces so that each can be its own module.
5+
A primary goal for the SDK is to provide modular and specific access to the protocols build on Wormhole.
76

7+
To address this goal, the SDK is structured into layers
88
```
9-
core/
10-
base/ -- Constants
11-
definitions/ -- VAA structures and module definitions
12-
connect/ -- Primary package and interface through Wormhole
13-
14-
platforms/ -- Platform specific logic
15-
evm/
16-
protocols/
17-
tokenBridge.ts
18-
cctp.ts
19-
chain.ts
20-
platform.ts
21-
...
22-
solana/
23-
protocols/
24-
tokenBridge.ts
25-
chain.ts
26-
platform.ts
27-
...
28-
...
9+
core/ -- Low level packages
10+
base/ -- Constants and utilities
11+
definitions/ -- Definitions of interfaces for Platforms/Protocols and Payload Layouts
12+
icons/ -- Logos for chains
13+
14+
connect/ -- Makes use of the interfaces in `definitions` to expose protocols in a platform independent way.
15+
16+
platforms/ -- Contains `Platform` and `Protocol` implementations
17+
evm/
18+
protocols/ -- Contains the Evm `Protocol` implementations
19+
core/ -- `EvmWormholeCore` implementation
20+
tokenBridge/ -- `EvmTokenBridge` implementation
21+
cctp/ `EvmCircleBridge` implementation
22+
...
23+
src/ -- Contains the Evm implementations for `Platform`, `Chain`, `Address`, etc...
24+
solana/ -- Contains Solana `Platform` and `Protocol` implementations
25+
etc...
26+
27+
sdk/ -- Metapackage that depeneds on the rest of the packages, meant to be a simpler way to install/use.
28+
29+
examples/ -- Examples, also used for README string replace
2930
```
3031

31-
# Concepts
32+
# Interfaces
3233

33-
The `Wormhole` class provides methods to interact with the Wormhole protocol by mapping chain parameters to the `Platform` and `Chain` specific implementations.
34+
Interfaces defined in `core/definitions` are implemented for each platform on which they are supported.
3435

35-
A `Platform` is a blockchain runtime, often shared across a number of chains (e.g. `Evm` platform for `Ethereum`, `Bsc`, `Polygon`, etc ...).
36+
## Platform Interfaces
3637

37-
A `Chain` is a specific blockchain, potentially with overrides for slight differences in the platform implementation.
38+
Several interfaces should be available for each platform supported.
3839

39-
A `Protocol` (fka `Module`) is a specific application on a `Chain`, it provides a set of methods that can be called to accomplish some action (e.g. `TokenBridge` allows send/receive/lookup token, etc...)
40+
- A `Platform` is a blockchain runtime, often shared across a number of chains (e.g. `Evm` platform for `Ethereum`, `Bsc`, `Polygon`, etc ...).
4041

41-
A `Signer` is an interface that provides a callback to sign one or more transaction objects. These signed transactions are sent to the blockchain to invoke some action.
42+
- A `Chain` is a specific blockchain, potentially with overrides for slight differences in the platform implementation.
4243

43-
An `Attestation` is a signed guarantee that some _thing_ happened on a remote chain, sent to the target chain to complete a transfer.
44+
- An `Address` provides parsing/formatting/conversion for platform specific addresses.
4445

46+
- A `Signer` is an interface that provides a callback to `sign` or `signAndSend` one or more transaction objects.
4547

46-
# Details
48+
> The Signer interface is intended to be flexible enough to allow devs to provide their own implementation with more specific transaction creation/configuration/submission logic than what could be covered in the default provided signers. It also allows for the creation of Signers that wrap hardware wallets or web wallets.
4749
48-
## Wormhole
50+
## Protocol Interfaces
4951

50-
Registers Platforms
52+
A Protocol (fka `Module`) is a specific application, it provides a set of methods that can be called to accomplish some action (e.g. `TokenBridge` allows `transfer`/`redeem`/`getWrappedAsset`, etc...)
5153

52-
Allows overriding chain specific configs (rpc, contract addresses, ...)
54+
To allow platform agnostic access to Protocols, each Platform that provides the protocol should have its own implementation.
5355

54-
Provides methods to get PlatformContext or ChainContext objects
55-
```ts
56-
wh.getPlatform("Evm")
57-
wh.getChain("Ethereum")
58-
```
59-
60-
Provides methods to create a `WormholeTransfer` for any `Protocol`
61-
```ts
62-
wh.tokenTransfer(...)
63-
wh.nftTransfer(...)
64-
wh.cctp(...)
65-
//...
66-
```
67-
68-
Provides methods to query an API for VAAs and token details
69-
```ts
70-
// grab a vaa with identifier
71-
wh.getVaa(...)
72-
// get the token details
73-
wh.getOriginalToken(...)
74-
wh.getWrappedToken(orig, chain)
75-
```
76-
77-
## Platform
78-
79-
Base class, implements Platform specific logic
80-
81-
Parse Addresses
82-
83-
Parse Message out of Transaction
84-
85-
Sign/Send/Wait
86-
87-
## ChainContext
88-
89-
Defined in abstract ChainContext class
90-
91-
Note: Dispatches many calls to the Platform, filling in details like ChainName and RPC
92-
93-
The `getRpc` method is the only platform specific thing _required_ to implement.
94-
95-
Responsible for holding RPC connection, initialized from default or overrides
96-
```ts
97-
cc.getRPC() // for evm -> ethers.Provider, for sol -> web3.Connection
98-
```
99-
100-
Holds references to Contract client
101-
102-
103-
<!--
104-
Not Implemented
105-
Provides methods to lookup details for contract addresses, finality, address parsers/formatters
106-
107-
```ts
108-
cc.getTokenBridgeAddress()
109-
cc.estimateFinality(txid)
110-
```
111-
-->
112-
113-
114-
## WormholeTransfer
115-
116-
Holds a reference to ChainContexts
117-
118-
Holds details about the transfer
119-
120-
Provides methods to step through the transfer process
121-
122-
## Glossary
123-
124-
- Network
125-
Mainnet, Testnet, Devnet
126-
- Platform
127-
A chain or group of chains within the same ecosystem that share common logic (e.g. EVM, Cosmwasm, etc)
128-
- Platform Context
129-
A class which implements a standardized format and set of methods. It may include additional chain-specific methods and logic.
130-
- Protocol
131-
A cross-chain application built on top of Wormhole (the core contracts are also considered a module)
132-
- Universal Address
133-
A 32-byte address, used by the wormhole contracts
134-
- Native Address (I think this should be called "Platform Address")
135-
An address in the standard chain-specific format
136-
- Native
137-
The "home" chain (e.g. ETH is native to Ethereum)
138-
- Foreign
139-
A non-native chain (e.g. ETH is foreign to Moonbeam)
140-
- VAA (Verified Action Approval)
141-
The core messaging primitive in Wormhole, it contains information about a message and a payload encoded as bytes. Once finality is achieved and it is observed by the majority of the guardians, it is signed and can then be used to complete a transfer on the destination chain
142-
- Payload
143-
Bytes that can be passed along with any wormhole message that contain application-specific data
144-
- Finality/Finality Threshold
145-
The required number of blocks to wait until a VAA is produced
146-
147-
# Discussion
148-
149-
150-
## What's the purpose of the Wormhole class?
151-
152-
Wormhole class provides the main interface to do _everything_
153-
154-
- Registers Platforms to access later -- constructor
155-
- Provides access to PlatformContexts -- getContext(ChainName)
156-
- Provides "shortcuts" to start a WormholeTransfer -- tokenTransfer/nftTransfer/cctp/...
157-
- Helpers for getting VAAs? or generally querying the API?
158-
- Abstract away chain-specific logic for easy mode access to methods
159-
160-
## What do we want from a PlatformContext and how is that different from a provider / common utilities for a given platform?
161-
162-
Provides Platform specific logic for a set of things
163-
164-
- Register Modules (contract/app specific functionality)
165-
- Translates Platform specific stuff to generic stuff (e.g. ethers.Provider => RPC connection)
166-
- Deals with Platform specific interaction w/ chain (approve on eth, postvaa on sol, ...)
167-
- Implements standardized method format
168-
169-
## What's the relationship between platforms/chains/providers?
170-
171-
- A Platform provides the logic for all chains that run on that platform
172-
- A Chain provides consts (rpc/contract addresses/chain specific overrides)
173-
- A Provider is just an RPC connection and is held by the Chain. Providers are an implementation detail.
174-
175-
## What's a signer vs. a wallet? Should signers have a provider (my answer: no)?
176-
177-
- A Signer is an interface to sign transactions
178-
- It _may_ be backed by a wallet but not necessarily, as long as it fulfils the interface
179-
180-
## Can we provide some way to make other non-standard applications available to use through the WormholeTransfer?
181-
182-
Say I have an app that defines its own protocol, can I provide something that adheres to the WormholeTransfer interface so a dev can install it and call it like the TokenTransfer?
56+
# Platform packages
18357

58+
Each platform has implementations of the relevant interfaces from `core/definitions` as well as implementations for each protocol supported on that platform.
18459

185-
# Outstanding Questions:
60+
The platform package should be the only one that depends on packages for that platform (eg ethersv6 for evm).
18661

187-
What is the preferred terminology to refer to either end of a cross-chain message: from/to, source/target or origin/destination?
62+
# Connect package
18863

189-
What is the preferred terminology for the core Wormhole layer? (i.e. Core Contracts or Wormhole Contracts)
64+
The `connect` package provides access to all the `Platform` and `Protocol` implementations through their interfaces.
19065

191-
Should we namespace export base/definitions?
66+
The `Wormhole` class represents a context to register specific Platforms and set some initial configuration overrides. It provides utility methods to do things like create a `ChainContext` or parse an address.
19267

193-
How should we think about xchain concepts without having xchain context?
68+
The `routes` directory contains the logic to make use of the Protocol implementations by composing a route through the use of one or more Protocol interfaces.
19469

195-
e.g.
196-
// need to implement universal univeral decoder?
197-
given eth address, and without installing evm platform, how do i turn it into a solana wrapped token without knowing how to fmt the address?
70+
# SDK package
19871

199-
// neet to tweak contracts on sol to support !ATA?
200-
given an xfer from eth=>sol, and without installing sol platform, how do i determine the ATA?
72+
The `@wormhole-foundation/sdk` package was created to reduce the confusion reported by devs around what they needed to install and use.
20173

74+
Because this project has strict separation of platform implementation packages, the registration of platforms and protocols is done as a side effect. As a result, naked imports may be required for lower level packages to be properly registered.
20275

203-
What is the benefit of costmap vs single fat object
76+
This package specifies _all_ platforms and protocols as dependencies which increases installed size but provides provides conditional exports for each `Platform` to allow for a smaller bundle size.
20477

205-
Why is network duped across platform/chaincontext/contracts?
78+
Each platform has a `PlatformDefiniton` containing the `Platform` specific implementations that can be imported directly or through the `PlatformLoader` which ensures the protocols are registered as well.

notes.md

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# SDK Notes
2+
3+
See the [DESIGN.md](./DESIGN.md) for overall design considerations.
4+
5+
This document details some things that could be improved about the SDK.
6+
7+
## General
8+
9+
The [token registry](./tokenRegistry/) directory is unused except for importing the tokens from connect, which is no longer necessary.
10+
11+
It is still possible to screw up a transfer (blackhole funds) if the higher level constructs (`WormholeTransfer` or `Route`) are not used and care is not taken to produce a transfer that is acceptable by the destination chain. I have no suggestions for this that would prevent the platform-specific-oddities from leaking into packages they have no business in besides "better documentation" or disallow it completely.
12+
13+
Examples:
14+
15+
- Invalid ATA receiver for Solana destined transfer. An [issue](https://github.com/wormhole-foundation/wormhole/issues/3992) has been filed to reduce the danger for this one.
16+
17+
- https://wormholescan.io/#/tx/0x1605bd06e15d46398c061bd2fc24e65c2b580d07c3e7a4ca9a0643bf91d16a7c
18+
- https://wormholescan.io/#/tx/DnEXtm2NdLhT5RszHc7nR7LPNATzGSP3kmbC2GQkAJyK
19+
20+
21+
- Incorrect contract address in payload, caused by a bug that allowed an empty address to be passed for the remote contract.
22+
23+
- https://wormholescan.io/#/tx/2g4nn6fWZCkphxeMGfqjzViZYo3XAYarYTSvTcxYY95JAtZvwVd7MKY6RWHhhHd8oBzeFWjuTkXNo4tdVVTwBWfo
24+
25+
26+
Docs and test coverage is lacking.
27+
28+
## Core
29+
30+
### Base
31+
32+
The [tokens](./core/base/src/constants/tokens) consts take up a lot of packed space in a widely used package for marginal benefit. Consider making these a wholly separate package that _can_ be installed and fetched when necessary.
33+
34+
The [nativeChainIds](./core/base/src/constants/nativeChainIds.ts) constants mix different chain id types, causing extra akward type checks to be done. Consider splitting these by platform so that when a `Chain` is passed, the type of chain id can be inferred. Also will help to distinguish between chain id _kinds_ (eip155 vs whatever) since they could be unique at least in that context.
35+
36+
The [Network](./core/base/src/constants/networks.ts) value "Devnet" is confusing to folks coming from Solana since it refers to some ci or local network configuration profile and what they actually want is "Testnet".
37+
38+
The network breakdown might serve better as a named configuration profile instead, where the dev would not have to, for example, map the name "Ethereum" to (Mainnet->Ethereum, Testnet->Sepolia), rather, that would be part of the configuration profile definition. Possibly defined as overrides from the defaults of "Mainnet"|"Testnet"|"Devnet".
39+
40+
This would constitute a large change since the Network type is a generic parameter for many other types.
41+
42+
The [layouts](./core/base/src/utils/layout/index.ts) could be broken out into their own package for more generic uses outside the context of the wormhole sdk.
43+
44+
### Definitions
45+
46+
47+
The [layout definitions](./core/definitions/src/protocols/tokenBridge/tokenBridgeLayout.ts) for the protocols are very difficult to read/comprehend from just source. We could have some way to write out the full object produced so that the fields it contains are easier to read.
48+
49+
The [Attestation/AttestationId](./core/definitions/src/attestation.ts) could be registered along with the protocol instead of having a hardcoded switch case. The current definition makes it very awkward to use for anything outside this repo, but since its used in the Routes, external "plugins" need to have _something_. This forces the Attestation type to be a punted `VAA<"Uint8Array">`
50+
51+
The [RPC](./core/definitions/src/rpc.ts) is a punted `any` type. It could benefit from the same type registration as others, where the exact type is set in some namespace so that type inteference would be happy with something like:
52+
53+
```ts
54+
(await ChainContext<"Mainnet", "Solana">.getRpc()) satisfies Connection
55+
```
56+
57+
The [protocols](./core/definitions/src/protocols/) could have **standard** fields in their respective `namespace` for things like:
58+
59+
- Which contracts are required (eg `Required<Contracts, 'tokenBridge' | 'coreBridge'>`)
60+
- The protocol name/payload names ([issue here](https://github.com/wormhole-foundation/wormhole-sdk-ts/issues/564))
61+
- The emitter address for the protocol
62+
- A disciminator/serde for its VAAs/payloads
63+
- Standardized Errors that may be thrown
64+
65+
Note: it is possible to enforce a namespace adheres to an interface
66+
```ts
67+
interface x { doit(): void; }
68+
interface z { dont(): void; }
69+
namespace y { export function doit () { return; } }
70+
// ok
71+
y satisfies x;
72+
// not ok, will not compile
73+
// y satisfies z;
74+
```
75+
76+
77+
78+
## Connect
79+
80+
The [Wormhole](./connect/src/wormhole.ts) class has spotty coverage of util methods. Some of the methods are awkward to have on `Wormhole` like `canonicalAddress` which is already an exported method.
81+
82+
Getting decent typehints for the [Route](./connect/src/routes/route.ts) implementations has been rough. We could, in the route, provide a typeguard that can be called to narrow the type to itself. This would be helpful to understand the exact types required as input (specific options per route, etc) and what is returned on output (more detailed route specific quote details, etc).
83+
84+
The [Receipt typeguards](./connect/src/types.ts) could also define `hasSourceInitiated`, `hasAttested`, etc for checking if the transfer is _past_ some step.
85+
86+
The [Wormholescan API](./connect/src/whscan-api.ts) could be better documented and possibly autogenerated from the swagger for the api.
87+
88+
The classes that implement the [WormholeTransfer](./connect/src/protocols/wormholeTransfer.ts) could be deprecated in favor of the `Route` usage. The underlying code could be preserved and made available in a static context where all args are provided rather than keeping state in the `WormholeTransfer` object.
89+
90+
## Platforms
91+
92+
Every Protocol implementation defines its own private `createUnsignedTransaction` function, which, kinda sucks.
93+
94+
The Signer implementations are bad at things like gas estimation or handling errors. They could also provide support for transaction review prior to signing.
95+
96+
97+
### Evm
98+
99+
The [addFrom/addValue/addChainId](./platforms/evm/src/types.ts) util functions could be made into a single "populate default fields" kind of function that sets the required fields.
100+
101+
Consider removing [Portico](./platforms/evm/protocols/portico/) completely from this repository and provide a new package similar to mayan or ntt outside of this repository.
102+
103+
### Solana
104+
105+
A lot of the code here was copy/pasted without regard to what was actually necessary. Consider purging any unused functions.
106+
107+
While the `Buffer` type has been kept out of most packages intentionally, the Solana packages have not been as strict. For web applications this can still be a pain, consider trying to purge it completely.
108+
109+
The [Unsigned Transaction](./platforms/solana/src/unsignedTransaction.ts) type can handle versioned transactions but we still only produce the legacy transaction type. We could produce the versioned transactions since they'll provide more features in the future, [issue here](https://github.com/wormhole-foundation/wormhole-sdk-ts/issues/163).
110+
111+
### Cosmwasm
112+
113+
There are some awkward [consts](./platforms/cosmwasm/src/constants.ts) for address prefix and average prices (??)
114+
115+
The IBC channel consts need to be updated with the [fetch-registry](./platforms/cosmwasm/scripts/fetch-registry.ts) script occasionally.
116+
117+
The IBC protocol could probably have just been `Gateway` instead, that is a new Protocol for `Gateway` specific methods could have been created instead of exposing ibc methods. The connect package `GatewayTransfer` is made awkard by the current setup.
118+
119+
### Sui
120+
121+
Disaster show wrt types, a lot of weird type checking to get some deeply nested field in a MoveValue.

0 commit comments

Comments
 (0)