trustless-generic-relayer/relayer_engine/pkgs/sdk/src/structs.ts

186 lines
4.5 KiB
TypeScript

import { BigNumber, ethers } from "ethers"
import { arrayify } from "ethers/lib/utils"
export enum RelayerPayloadId {
Delivery = 1,
// DeliveryStatus = 3,
}
export enum DeliveryStatus {
WaitingForVAA = "Waiting for VAA",
PendingDelivery = "Pending Delivery",
DeliverySuccess = "Delivery Success",
ReceiverFailure = "Receiver Failure",
InvalidRedelivery = "Invalid Redelivery",
ForwardRequestSuccess = "Forward Request Success",
ForwardRequestFailure = "Forward Request Failure",
ThisShouldNeverHappen = "This should never happen. Contact Support.",
DeliveryDidntHappenWithinRange = "Delivery didn't happen within given block range",
}
export interface DeliveryInstructionsContainer {
payloadId: number // 1
messages: MessageInfo[]
instructions: DeliveryInstruction[]
}
export interface MessageInfo {
payloadType: MessageInfoType
emitterAddress?: Buffer
sequence?: BigNumber
vaaHash?: Buffer
}
export interface DeliveryInstruction {
targetChain: number
targetAddress: Buffer
refundAddress: Buffer
maximumRefundTarget: BigNumber
receiverValueTarget: BigNumber
executionParameters: ExecutionParameters
}
export interface ExecutionParameters {
version: number
gasLimit: number
providerDeliveryAddress: Buffer
}
export enum MessageInfoType {
EMITTER_SEQUENCE = 0,
VAAHASH = 1,
}
export function parseWormholeRelayerPayloadType(
stringPayload: string | Buffer | Uint8Array
): RelayerPayloadId {
const payload =
typeof stringPayload === "string" ? arrayify(stringPayload) : stringPayload
if (payload[0] == 0 || payload[0] >= 3) {
throw new Error("Unrecogned payload type " + payload[0])
}
return payload[0]
}
export function parseWormholeRelayerSend(bytes: Buffer): DeliveryInstructionsContainer {
let idx = 0
const payloadId = bytes.readUInt8(idx)
if (payloadId !== RelayerPayloadId.Delivery) {
throw new Error(
`Expected Delivery payload type (${RelayerPayloadId.Delivery}), found: ${payloadId}`
)
}
idx += 1
const numMessages = bytes.readUInt8(idx)
idx += 1
let messages = [] as MessageInfo[]
for (let i = 0; i < numMessages; ++i) {
const res = parseMessageInfo(bytes, idx)
idx = res[1]
messages.push(res[0])
}
const numInstructions = bytes.readUInt8(idx)
idx += 1
let instructions = [] as DeliveryInstruction[]
for (let i = 0; i < numInstructions; ++i) {
const targetChain = bytes.readUInt16BE(idx)
idx += 2
const targetAddress = bytes.slice(idx, idx + 32)
idx += 32
const refundAddress = bytes.slice(idx, idx + 32)
idx += 32
const maximumRefundTarget = ethers.BigNumber.from(
Uint8Array.prototype.subarray.call(bytes, idx, idx + 32)
)
idx += 32
const receiverValueTarget = ethers.BigNumber.from(
Uint8Array.prototype.subarray.call(bytes, idx, idx + 32)
)
idx += 32
let res = parseWormholeRelayerExecutionParameters(bytes, idx)
const executionParameters = res[0]
idx = res[1]
instructions.push(
// dumb typechain format
{
targetChain,
targetAddress,
refundAddress,
maximumRefundTarget,
receiverValueTarget,
executionParameters,
}
)
}
return {
payloadId,
messages,
instructions,
}
}
function parseMessageInfo(bytes: Buffer, idx: number): [MessageInfo, number] {
const payloadId = bytes.readUint8(idx)
idx += 1
const payloadType = bytes.readUint8(idx) as MessageInfoType
idx += 1
if (payloadType == MessageInfoType.EMITTER_SEQUENCE) {
const emitterAddress = bytes.slice(idx, idx + 32)
idx += 32
const sequence = ethers.BigNumber.from(
Uint8Array.prototype.subarray.call(bytes, idx, idx + 8)
)
idx += 8
return [
{
payloadType,
emitterAddress,
sequence,
},
idx,
]
} else if (payloadType == MessageInfoType.VAAHASH) {
const vaaHash = bytes.slice(idx, idx + 32)
idx += 32
return [
{
payloadType,
vaaHash,
},
idx,
]
} else {
throw new Error("Unexpected MessageInfo payload type")
}
}
function parseWormholeRelayerExecutionParameters(
bytes: Buffer,
idx: number
): [ExecutionParameters, number] {
const version = bytes.readUInt8(idx)
idx += 1
const gasLimit = bytes.readUint32BE(idx)
idx += 4
const providerDeliveryAddress = bytes.slice(idx, idx + 32)
idx += 32
return [{ version, gasLimit, providerDeliveryAddress }, idx]
}
/*
* Helpers
*/
export function dbg<T>(x: T, msg?: string): T {
if (msg) {
console.log("[DEBUG] " + msg)
}
console.log(x)
return x
}