Skip to content

Commit

Permalink
refactor addresses (#178)
Browse files Browse the repository at this point in the history
  • Loading branch information
barnjamin committed Dec 21, 2023
1 parent 81e4624 commit 43be810
Show file tree
Hide file tree
Showing 62 changed files with 264 additions and 352 deletions.
11 changes: 5 additions & 6 deletions connect/src/protocols/cctpTransfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
isCircleTransferDetails,
isTransactionIdentifier,
isWormholeMessageId,
nativeChainAddress,
} from "@wormhole-foundation/sdk-definitions";

import { signSendWait } from "../common";
Expand Down Expand Up @@ -129,16 +128,16 @@ export class CircleTransfer<N extends Network = Network>

let automatic = false;
if (wormholeRelayer) {
const relayerAddress = nativeChainAddress(
const relayerAddress = Wormhole.chainAddress(
chain,
wormholeRelayer,
).address.toUniversalAddress();
automatic = vaa.payloadName === "TransferRelay" && rcvAddress.equals(relayerAddress);
}

const details: CircleTransferDetails = {
from: nativeChainAddress(from.chain, vaa.payload.caller),
to: nativeChainAddress(rcvChain, rcvAddress),
from: { chain: from.chain, address: vaa.payload.caller },
to: { chain: rcvChain, address: rcvAddress },
amount: vaa.payload.token.amount,
automatic,
};
Expand All @@ -165,8 +164,8 @@ export class CircleTransfer<N extends Network = Network>
const rcvChain = circle.toCircleChain(msg.destinationDomain);

const details: CircleTransferDetails = {
from: nativeChainAddress(sendChain, xferSender),
to: nativeChainAddress(rcvChain, xferReceiver),
from: { chain: sendChain, address: xferSender },
to: { chain: rcvChain, address: xferReceiver },
amount: burnMessage.amount,
automatic: false,
};
Expand Down
5 changes: 2 additions & 3 deletions connect/src/protocols/gatewayTransfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {
chainToPlatform,
encoding,
toChain,
PlatformToChains,
} from "@wormhole-foundation/sdk-base";
import { PlatformToChains } from "@wormhole-foundation/sdk-base/src";
import {
ChainAddress,
ChainContext,
Expand All @@ -25,7 +25,6 @@ import {
isGatewayTransferDetails,
isTransactionIdentifier,
isWormholeMessageId,
nativeChainAddress,
toGatewayMsg,
toNative,
AttestationId,
Expand Down Expand Up @@ -200,7 +199,7 @@ export class GatewayTransfer<N extends Network = Network> implements WormholeTra
const recipientAddress = encoding.bytes.decode(
encoding.b64.decode(maybeWithPayload.recipient),
);
to = nativeChainAddress(destChain, recipientAddress);
to = Wormhole.chainAddress(destChain, recipientAddress);
} catch {
/*Ignoring, throws if not the payload isnt JSON*/
}
Expand Down
36 changes: 22 additions & 14 deletions connect/src/protocols/tokenTransfer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { Chain, Network, PlatformToChains, encoding, toChain } from "@wormhole-foundation/sdk-base";
import { Platform } from "@wormhole-foundation/sdk-base/dist/cjs";
import { ChainToPlatform } from "@wormhole-foundation/sdk-base/src";
import {
ChainToPlatform,
Platform,
Chain,
Network,
PlatformToChains,
encoding,
toChain,
} from "@wormhole-foundation/sdk-base";
import {
AttestationId,
ChainContext,
Signer,
TokenAddress,
Expand All @@ -16,16 +23,15 @@ import {
isTokenTransferDetails,
isTransactionIdentifier,
isWormholeMessageId,
nativeChainAddress,
toNative,
AttestationId,
toUniversal,
} from "@wormhole-foundation/sdk-definitions";
import { signSendWait } from "../common";
import { DEFAULT_TASK_TIMEOUT } from "../config";
import { Wormhole } from "../wormhole";
import {
TransferReceipt,
TransferQuote,
TransferReceipt,
TransferState,
WormholeTransfer,
} from "../wormholeTransfer";
Expand Down Expand Up @@ -285,7 +291,8 @@ export class TokenTransfer<N extends Network = Network>

const receipt = TokenTransfer.getReceipt(xfer);
if (receipt.state === TransferState.SourceInitiated) {
if (receipt.originTxs.length === 0) throw "Invalid state transition";
if (receipt.originTxs.length === 0)
throw "Invalid state transition: no originating transactions";

if (!receipt.attestation || !receipt.attestation?.emitter) {
const initTx = receipt.originTxs[receipt.originTxs.length - 1]!;
Expand All @@ -302,7 +309,8 @@ export class TokenTransfer<N extends Network = Network>

let vaa = undefined;
if (receipt.state == TransferState.SourceFinalized) {
if (!receipt.attestation || !receipt.attestation.emitter) throw "Invalid state transition";
if (!receipt.attestation || !receipt.attestation.emitter)
throw "Invalid state transition: no attestation id";

vaa = xfer.vaas && xfer.vaas.length > 0 && xfer.vaas[0]!.vaa ? xfer.vaas[0].vaa : undefined;
// we need to get the attestation so we can deliver it
Expand Down Expand Up @@ -463,8 +471,7 @@ export class TokenTransfer<N extends Network = Network>

// if the token id is actually native to the destination, return it
if (lookup.chain === dstChain.chain) {
const { chain, address } = lookup;
return { chain, address: address.toNative(chain) } as TokenId<DC>;
return lookup as TokenId<typeof dstChain.chain>;
}

// otherwise, figure out what the token address representing the wormhole-wrapped token we're transferring
Expand All @@ -478,9 +485,7 @@ export class TokenTransfer<N extends Network = Network>
const { chain, address } = vaa.payload.to;
const { tokenBridgeRelayer } = wh.config.chains[chain]!.contracts;

const relayerAddress = tokenBridgeRelayer
? nativeChainAddress(chain, tokenBridgeRelayer).address.toUniversalAddress()
: null;
const relayerAddress = tokenBridgeRelayer ? toUniversal(chain, tokenBridgeRelayer) : null;

return (
vaa.payloadName === "TransferWithPayload" &&
Expand Down Expand Up @@ -613,7 +618,10 @@ export class TokenTransfer<N extends Network = Network>
},
}),
);
_transfer.to = nativeChainAddress(_transfer.to.chain, dstChain.config.contracts!.translator!);
_transfer.to = Wormhole.chainAddress(
_transfer.to.chain,
dstChain.config.contracts!.translator!,
);
}

return _transfer;
Expand Down
3 changes: 1 addition & 2 deletions connect/src/tasks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Chain, Network, Platform } from "@wormhole-foundation/sdk-base";
import { PlatformToChains, Chain, Network, Platform } from "@wormhole-foundation/sdk-base";
import {
GatewayTransferMsg,
GatewayTransferWithPayloadMsg,
Expand All @@ -14,7 +14,6 @@ import {
isTransactionIdentifier,
} from "@wormhole-foundation/sdk-definitions";
import { DEFAULT_TASK_TIMEOUT } from "./config";
import { PlatformToChains } from "@wormhole-foundation/sdk-base/src";

// A task is a retryable function, it should return a Thing or null for a failure case
// It should throw on a permanent failure instead of retrying
Expand Down
8 changes: 4 additions & 4 deletions connect/src/wormhole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
PlatformToChains,
chainToPlatform,
circle,
ChainToPlatform,
} from "@wormhole-foundation/sdk-base";
import {
ChainAddress,
Expand All @@ -22,10 +23,10 @@ import {
deserialize,
toNative,
} from "@wormhole-foundation/sdk-definitions";
import { WormholeConfig, CONFIG, DEFAULT_TASK_TIMEOUT } from "./config";
import { getCircleAttestationWithRetry } from "./circle-api";
import { CONFIG, DEFAULT_TASK_TIMEOUT, WormholeConfig } from "./config";
import { CircleTransfer } from "./protocols/cctpTransfer";
import { TokenTransfer } from "./protocols/tokenTransfer";
import { getCircleAttestationWithRetry } from "./circle-api";
import { retry } from "./tasks";
import {
TransactionStatus,
Expand All @@ -34,7 +35,6 @@ import {
getVaaBytesWithRetry,
getVaaWithRetry,
} from "./whscan-api";
import { ChainToPlatform } from "@wormhole-foundation/sdk-base/src";

type PlatformMap<N extends Network, P extends Platform = Platform> = Map<P, PlatformContext<N, P>>;
type ChainMap<N extends Network, C extends Chain = Chain> = Map<
Expand Down Expand Up @@ -356,7 +356,7 @@ export class Wormhole<N extends Network> {
* @returns The ChainAddress
*/
static chainAddress<C extends Chain>(chain: C, address: string): ChainAddress<C> {
return { chain, address: toNative(chain, address) };
return { chain, address: Wormhole.parseAddress(chain, address) };
}

/**
Expand Down
1 change: 1 addition & 0 deletions core/base/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export {
isPlatform,
platformToChains,
chainToPlatform,
platformToAddressFormat,
} from "./platforms";

export * as platform from "./platforms";
Expand Down
15 changes: 5 additions & 10 deletions core/definitions/__tests__/circleMessage.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { deserializeLayout, circle, encoding } from "@wormhole-foundation/sdk-base";
import { deserializeLayout, circle, encoding, contracts } from "@wormhole-foundation/sdk-base";
import { circleMessageLayout } from "../src/protocols/cctp";
import { UniversalAddress } from "../src";
import { circleContracts } from "@wormhole-foundation/sdk-base/src/constants/contracts";

const ethAddressToUniversal = (address: string) => {
return new UniversalAddress("00".repeat(12) + address.slice(2));
Expand All @@ -18,20 +17,16 @@ describe("Circle Message tests", function () {
const toChain = "Avalanche";

// same sender and receiver
const accountSender = ethAddressToUniversal(
"0x6603b4a7e29dfbdb6159c395a915e74757c1fb13",
);
const accountSender = ethAddressToUniversal("0x6603b4a7e29dfbdb6159c395a915e74757c1fb13");

const actualSender = ethAddressToUniversal(
circleContracts("Testnet", fromChain).tokenMessenger,
contracts.circleContracts("Testnet", fromChain).tokenMessenger,
);
const actualReceiver = ethAddressToUniversal(
circleContracts("Testnet", toChain).tokenMessenger,
contracts.circleContracts("Testnet", toChain).tokenMessenger,
);

const tokenAddress = ethAddressToUniversal(
circle.usdcContract("Testnet", fromChain),
);
const tokenAddress = ethAddressToUniversal(circle.usdcContract("Testnet", fromChain));

const decoded = deserializeLayout(circleMessageLayout, orig);
expect(decoded.sourceDomain).toEqual(fromChain);
Expand Down
45 changes: 20 additions & 25 deletions core/definitions/src/address.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {
Chain,
isChain,
ChainToPlatform,
Platform,
chainToPlatform,
ChainToPlatform,
platformToAddressFormat,
} from "@wormhole-foundation/sdk-base";

//TODO BRRRR circular include!!
Expand Down Expand Up @@ -42,22 +42,16 @@ declare global {

export type MappedPlatforms = keyof WormholeNamespace.PlatformToNativeAddressMapping;

type ChainOrPlatformToPlatform<T extends Chain | Platform> = T extends Chain
? ChainToPlatform<T>
: T;

type GetNativeAddress<T extends Platform> = T extends MappedPlatforms
? WormholeNamespace.PlatformToNativeAddressMapping[T]
: never;

export type NativeAddress<T extends Platform | Chain> = GetNativeAddress<
ChainOrPlatformToPlatform<T>
>;
export type NativeAddress<C extends Chain> = GetNativeAddress<ChainToPlatform<C>>;

export type UniversalOrNative<T extends Platform | Chain> = UniversalAddress | NativeAddress<T>;
export type UniversalOrNative<T extends Chain> = UniversalAddress | NativeAddress<T>;

export type AccountAddress<T extends Chain | Platform> = UniversalOrNative<T>;
export type TokenAddress<T extends Chain | Platform> = UniversalOrNative<T> | "native";
export type AccountAddress<T extends Chain> = UniversalOrNative<T>;
export type TokenAddress<T extends Chain> = UniversalOrNative<T> | "native";

export type ChainAddress<C extends Chain = Chain> = {
readonly chain: C;
Expand All @@ -78,24 +72,25 @@ export function registerNative<P extends Platform>(platform: P, ctr: NativeAddre
nativeFactory.set(platform, ctr);
}

export function nativeIsRegistered<T extends Platform | Chain>(chainOrPlatform: T): boolean {
const platform: Platform = isChain(chainOrPlatform)
? chainToPlatform.get(chainOrPlatform)!
: chainOrPlatform;

export function nativeIsRegistered<C extends Chain>(chain: C): boolean {
const platform: Platform = chainToPlatform.get(chain);
return nativeFactory.has(platform);
}

export function toNative<T extends Platform | Chain>(
chainOrPlatform: T,
export function toNative<C extends Chain>(
chain: C,
ua: UniversalAddress | string | Uint8Array,
): NativeAddress<T> {
const platform: Platform = isChain(chainOrPlatform)
? chainToPlatform.get(chainOrPlatform)!
: chainOrPlatform;

): NativeAddress<C> {
const platform: Platform = chainToPlatform.get(chain);
const nativeCtr = nativeFactory.get(platform);
if (!nativeCtr) throw new Error(`No native address type registered for platform ${platform}`);
return new nativeCtr(ua) as unknown as NativeAddress<C>;
}

return new nativeCtr(ua) as unknown as NativeAddress<T>;
export function toUniversal<C extends Chain>(
chain: C,
address: string | Uint8Array,
): UniversalAddress {
const platform: Platform = chainToPlatform.get(chain);
return new UniversalAddress(address, platformToAddressFormat.get(platform));
}
4 changes: 1 addition & 3 deletions core/definitions/src/layout-items/circle.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { circle } from "@wormhole-foundation/sdk-base";
import { UintLayoutItem } from "@wormhole-foundation/sdk-base/dist/cjs";
import { CustomConversion } from "@wormhole-foundation/sdk-base/src";
import { UintLayoutItem, CustomConversion, circle } from "@wormhole-foundation/sdk-base";

export const circleDomainItem = {
binary: "uint",
Expand Down
9 changes: 6 additions & 3 deletions core/definitions/src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ export type ProtocolImplementation<
: never;

export interface ProtocolInitializer<P extends Platform, PN extends ProtocolName> {
fromRpc(rpc: RpcConnection<P>, config: ChainsConfig<Network, P>): ProtocolImplementation<P, PN>;
fromRpc(
rpc: RpcConnection<P>,
config: ChainsConfig<Network, P>,
): Promise<ProtocolImplementation<P, PN>>;
}

const protocolFactory = new Map<
Expand Down Expand Up @@ -74,7 +77,7 @@ export function getProtocolInitializer<P extends Platform, PN extends ProtocolNa
const pctr = protocols.get(protocol);
if (!pctr) throw new Error(`No protocol registered for ${platform}:${protocol}`);

return pctr as ProtocolInitializer<P, PN>;
return pctr;
}

export const create = <N extends Network, P extends Platform, PN extends ProtocolName, T>(
Expand All @@ -84,5 +87,5 @@ export const create = <N extends Network, P extends Platform, PN extends Protoco
config: ChainsConfig<N, P>,
): Promise<T> => {
const pctr = getProtocolInitializer(platform, protocol);
return pctr.fromRpc(rpc, config) as Promise<T>;
return pctr.fromRpc(rpc, config);
};
4 changes: 2 additions & 2 deletions core/definitions/src/protocols/core.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Network, Platform } from "@wormhole-foundation/sdk-base";
import { PlatformToChains } from "@wormhole-foundation/sdk-base/src";
import { PlatformToChains, Network, Platform } from "@wormhole-foundation/sdk-base";
import { AccountAddress } from "../address";
import { WormholeMessageId } from "../attestation";
import { TxHash } from "../types";
import { UnsignedTransaction } from "../unsignedTransaction";
import { VAA } from "../vaa";

export interface WormholeCore<
N extends Network,
P extends Platform,
Expand Down
Loading

0 comments on commit 43be810

Please sign in to comment.