-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#252 - add warning for VAAs not compatible with token bridge to be re…
…deemed, like CCTP for instance
- Loading branch information
1 parent
781738c
commit 30ecd63
Showing
4 changed files
with
188 additions
and
23 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
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,128 @@ | ||
import { | ||
ChainId, | ||
ParsedVaa, | ||
hexToUint8Array, | ||
parseNFTPayload, | ||
parseTransferPayload, | ||
parseVaa, | ||
tryHexToNativeString, | ||
} from "@certusone/wormhole-sdk"; | ||
import { useMemo } from "react"; | ||
import { | ||
getNFTBridgeAddressForChain, | ||
getTokenBridgeAddressForChain, | ||
} from "../utils/consts"; | ||
|
||
enum VAAType { | ||
UNKNOWN = 0, | ||
TRANSFER = 1, | ||
ATTEST = 2, | ||
TRANSFER_WITH_PAYLOAD = 3, | ||
} | ||
|
||
interface ParserPayload<T> { | ||
(buffer: Buffer): T; | ||
} | ||
|
||
function parsePayload<T>( | ||
payload: Buffer, | ||
parser: ParserPayload<T> | ||
): T | undefined { | ||
try { | ||
if (payload) { | ||
return parser(payload); | ||
} | ||
} catch (err) { | ||
console.debug(`Failed to parse payload with ${parser}`, err); | ||
} | ||
} | ||
|
||
function getPayloadType(payload: Buffer): VAAType { | ||
try { | ||
const type = payload.readInt8(0); | ||
if (type > 0 || type <= 3) { | ||
return type; | ||
} | ||
} catch (err) { | ||
console.debug(`Failed to parse type from payload`, err); | ||
} | ||
return VAAType.UNKNOWN; | ||
} | ||
|
||
function parseVaaFromHexString(hexVaa: string): ParsedVaa { | ||
try { | ||
return parseVaa(hexToUint8Array(hexVaa)); | ||
} catch (err) { | ||
console.debug(err); | ||
} | ||
return {} as ParsedVaa; | ||
} | ||
|
||
function itWasEmittedFrom( | ||
emitterAddress: Buffer, | ||
emitterChain: number, | ||
getAddressFn: (chainId: ChainId) => string | ||
): boolean { | ||
try { | ||
const chainId = emitterChain as ChainId; | ||
const vaaEmitterAddress = tryHexToNativeString( | ||
emitterAddress?.toString("hex"), | ||
chainId | ||
); | ||
return ( | ||
getAddressFn(chainId)?.toUpperCase() === vaaEmitterAddress?.toUpperCase() | ||
); | ||
} catch (err) { | ||
console.debug(err); | ||
} | ||
return false; | ||
} | ||
|
||
function itIsASupportedType( | ||
type: VAAType, | ||
...supportedTypes: VAAType[] | ||
): boolean { | ||
return supportedTypes.includes(type); | ||
} | ||
|
||
export function useVaaVerifier(hexVaa: string) { | ||
const vaa = useMemo(() => parseVaaFromHexString(hexVaa), [hexVaa]); | ||
const vaaEmitterChain = useMemo(() => vaa?.emitterChain as ChainId, [vaa]); | ||
const vaaEmitterAddress = useMemo(() => vaa?.emitterAddress, [vaa]); | ||
const nft = useMemo(() => parsePayload(vaa?.payload, parseNFTPayload), [vaa]); | ||
const transfer = useMemo( | ||
() => parsePayload(vaa?.payload, parseTransferPayload), | ||
[vaa] | ||
); | ||
const payloadType = useMemo(() => getPayloadType(vaa?.payload), [vaa]); | ||
const itIsTokenBridgeTransfer = useMemo( | ||
() => | ||
itWasEmittedFrom( | ||
vaaEmitterAddress, | ||
vaaEmitterChain, | ||
getTokenBridgeAddressForChain | ||
) && | ||
itIsASupportedType( | ||
payloadType, | ||
VAAType.TRANSFER, | ||
VAAType.TRANSFER_WITH_PAYLOAD | ||
), | ||
[vaaEmitterAddress, vaaEmitterChain, payloadType] | ||
); | ||
const itIsNFTTransfer = useMemo( | ||
() => | ||
itWasEmittedFrom( | ||
vaaEmitterAddress, | ||
vaaEmitterChain, | ||
getNFTBridgeAddressForChain | ||
) && itIsASupportedType(payloadType, VAAType.TRANSFER), | ||
[vaaEmitterAddress, vaaEmitterChain, payloadType] | ||
); | ||
return { | ||
transfer, | ||
nft, | ||
payloadType, | ||
itIsTokenBridgeTransfer, | ||
itIsNFTTransfer, | ||
}; | ||
} |