structs.go 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108
  1. package vaa
  2. import (
  3. "bytes"
  4. "crypto/ecdsa"
  5. "encoding"
  6. "encoding/binary"
  7. "encoding/hex"
  8. "errors"
  9. "fmt"
  10. "io"
  11. "math/big"
  12. "strings"
  13. "time"
  14. "github.com/ethereum/go-ethereum/common"
  15. "github.com/ethereum/go-ethereum/crypto"
  16. )
  17. type (
  18. // VAA is a verifiable action approval of the Wormhole protocol
  19. VAA struct {
  20. // Version of the VAA schema
  21. Version uint8
  22. // GuardianSetIndex is the index of the guardian set that signed this VAA
  23. GuardianSetIndex uint32
  24. // SignatureData is the signature of the guardian set
  25. Signatures []*Signature
  26. // Timestamp when the VAA was created
  27. Timestamp time.Time
  28. // Nonce of the VAA
  29. Nonce uint32
  30. // Sequence of the VAA
  31. Sequence uint64
  32. /// ConsistencyLevel of the VAA
  33. ConsistencyLevel uint8
  34. // EmitterChain the VAA was emitted on
  35. EmitterChain ChainID
  36. // EmitterAddress of the contract that emitted the Message
  37. EmitterAddress Address
  38. // Payload of the message
  39. Payload []byte
  40. }
  41. // ChainID of a Wormhole chain
  42. ChainID uint16
  43. // Action of a VAA
  44. Action uint8
  45. // Address is a Wormhole protocol address, it contains the native chain's address. If the address data type of a
  46. // chain is < 32bytes the value is zero-padded on the left.
  47. Address [32]byte
  48. // Signature of a single guardian
  49. Signature struct {
  50. // Index of the validator
  51. Index uint8
  52. // Signature data
  53. Signature SignatureData
  54. }
  55. SignatureData [65]byte
  56. Observation struct {
  57. // Index of the observation in a Batch array
  58. Index uint8
  59. // Signed Observation data
  60. Observation *VAA
  61. }
  62. TransferPayloadHdr struct {
  63. Type uint8
  64. Amount *big.Int
  65. OriginAddress Address
  66. OriginChain ChainID
  67. TargetAddress Address
  68. TargetChain ChainID
  69. }
  70. // Attestation interface contains the methods common to all VAA types
  71. Attestation interface {
  72. encoding.BinaryMarshaler
  73. encoding.BinaryUnmarshaler
  74. serializeBody()
  75. signingBody() []byte
  76. SigningMsg() common.Hash
  77. VerifySignatures(addrs []common.Address) bool
  78. UniqueID() string
  79. HexDigest() string
  80. AddSignature(key *ecdsa.PrivateKey, index uint8)
  81. GetEmitterChain() ChainID
  82. }
  83. )
  84. const (
  85. ConsistencyLevelPublishImmediately = uint8(200)
  86. ConsistencyLevelSafe = uint8(201)
  87. )
  88. func (a Address) MarshalJSON() ([]byte, error) {
  89. return []byte(fmt.Sprintf(`"%s"`, a)), nil
  90. }
  91. // Standard marshal stores the Address like this: "[0,0,0,0,0,0,0,0,0,0,0,0,2,144,251,22,114,8,175,69,91,177,55,120,1,99,183,183,169,161,12,22]"
  92. // The above MarshalJSON stores it like this (66 bytes): ""0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16""
  93. func (a *Address) UnmarshalJSON(data []byte) error {
  94. addr, err := StringToAddress(strings.Trim(string(data), `"`))
  95. if err != nil {
  96. return err
  97. }
  98. *a = addr
  99. return nil
  100. }
  101. func (a Address) String() string {
  102. return hex.EncodeToString(a[:])
  103. }
  104. func (a Address) Bytes() []byte {
  105. return a[:]
  106. }
  107. func (a SignatureData) MarshalJSON() ([]byte, error) {
  108. return []byte(fmt.Sprintf(`"%s"`, a)), nil
  109. }
  110. func (a SignatureData) String() string {
  111. return hex.EncodeToString(a[:])
  112. }
  113. func (c ChainID) String() string {
  114. switch c {
  115. case ChainIDUnset:
  116. return "unset"
  117. case ChainIDSolana:
  118. return "solana"
  119. case ChainIDEthereum:
  120. return "ethereum"
  121. case ChainIDTerra:
  122. return "terra"
  123. case ChainIDBSC:
  124. return "bsc"
  125. case ChainIDPolygon:
  126. return "polygon"
  127. case ChainIDAvalanche:
  128. return "avalanche"
  129. case ChainIDOasis:
  130. return "oasis"
  131. case ChainIDAlgorand:
  132. return "algorand"
  133. case ChainIDAurora:
  134. return "aurora"
  135. case ChainIDFantom:
  136. return "fantom"
  137. case ChainIDKarura:
  138. return "karura"
  139. case ChainIDAcala:
  140. return "acala"
  141. case ChainIDKlaytn:
  142. return "klaytn"
  143. case ChainIDCelo:
  144. return "celo"
  145. case ChainIDNear:
  146. return "near"
  147. case ChainIDMoonbeam:
  148. return "moonbeam"
  149. case ChainIDTerra2:
  150. return "terra2"
  151. case ChainIDInjective:
  152. return "injective"
  153. case ChainIDOsmosis:
  154. return "osmosis"
  155. case ChainIDSui:
  156. return "sui"
  157. case ChainIDAptos:
  158. return "aptos"
  159. case ChainIDArbitrum:
  160. return "arbitrum"
  161. case ChainIDOptimism:
  162. return "optimism"
  163. case ChainIDGnosis:
  164. return "gnosis"
  165. case ChainIDPythNet:
  166. return "pythnet"
  167. case ChainIDXpla:
  168. return "xpla"
  169. case ChainIDBtc:
  170. return "btc"
  171. case ChainIDBase:
  172. return "base"
  173. case ChainIDFileCoin:
  174. return "filecoin"
  175. case ChainIDSei:
  176. return "sei"
  177. case ChainIDRootstock:
  178. return "rootstock"
  179. case ChainIDScroll:
  180. return "scroll"
  181. case ChainIDMantle:
  182. return "mantle"
  183. case ChainIDBlast:
  184. return "blast"
  185. case ChainIDXLayer:
  186. return "xlayer"
  187. case ChainIDLinea:
  188. return "linea"
  189. case ChainIDBerachain:
  190. return "berachain"
  191. case ChainIDSeiEVM:
  192. return "seievm"
  193. case ChainIDEclipse:
  194. return "eclipse"
  195. case ChainIDBOB:
  196. return "bob"
  197. case ChainIDSnaxchain:
  198. return "snaxchain"
  199. case ChainIDUnichain:
  200. return "unichain"
  201. case ChainIDWorldchain:
  202. return "worldchain"
  203. case ChainIDInk:
  204. return "ink"
  205. case ChainIDHyperEVM:
  206. return "hyperevm"
  207. case ChainIDMonad:
  208. return "monad"
  209. case ChainIDMovement:
  210. return "movement"
  211. case ChainIDMezo:
  212. return "mezo"
  213. case ChainIDWormchain:
  214. return "wormchain"
  215. case ChainIDCosmoshub:
  216. return "cosmoshub"
  217. case ChainIDEvmos:
  218. return "evmos"
  219. case ChainIDKujira:
  220. return "kujira"
  221. case ChainIDNeutron:
  222. return "neutron"
  223. case ChainIDCelestia:
  224. return "celestia"
  225. case ChainIDStargaze:
  226. return "stargaze"
  227. case ChainIDSeda:
  228. return "seda"
  229. case ChainIDDymension:
  230. return "dymension"
  231. case ChainIDProvenance:
  232. return "provenance"
  233. case ChainIDNoble:
  234. return "noble"
  235. case ChainIDSepolia:
  236. return "sepolia"
  237. case ChainIDArbitrumSepolia:
  238. return "arbitrum_sepolia"
  239. case ChainIDBaseSepolia:
  240. return "base_sepolia"
  241. case ChainIDOptimismSepolia:
  242. return "optimism_sepolia"
  243. case ChainIDHolesky:
  244. return "holesky"
  245. case ChainIDPolygonSepolia:
  246. return "polygon_sepolia"
  247. default:
  248. return fmt.Sprintf("unknown chain ID: %d", c)
  249. }
  250. }
  251. func ChainIDFromString(s string) (ChainID, error) {
  252. s = strings.ToLower(s)
  253. switch s {
  254. case "solana":
  255. return ChainIDSolana, nil
  256. case "ethereum":
  257. return ChainIDEthereum, nil
  258. case "terra":
  259. return ChainIDTerra, nil
  260. case "bsc":
  261. return ChainIDBSC, nil
  262. case "polygon":
  263. return ChainIDPolygon, nil
  264. case "avalanche":
  265. return ChainIDAvalanche, nil
  266. case "oasis":
  267. return ChainIDOasis, nil
  268. case "algorand":
  269. return ChainIDAlgorand, nil
  270. case "aurora":
  271. return ChainIDAurora, nil
  272. case "fantom":
  273. return ChainIDFantom, nil
  274. case "karura":
  275. return ChainIDKarura, nil
  276. case "acala":
  277. return ChainIDAcala, nil
  278. case "klaytn":
  279. return ChainIDKlaytn, nil
  280. case "celo":
  281. return ChainIDCelo, nil
  282. case "near":
  283. return ChainIDNear, nil
  284. case "moonbeam":
  285. return ChainIDMoonbeam, nil
  286. case "terra2":
  287. return ChainIDTerra2, nil
  288. case "injective":
  289. return ChainIDInjective, nil
  290. case "osmosis":
  291. return ChainIDOsmosis, nil
  292. case "sui":
  293. return ChainIDSui, nil
  294. case "aptos":
  295. return ChainIDAptos, nil
  296. case "arbitrum":
  297. return ChainIDArbitrum, nil
  298. case "optimism":
  299. return ChainIDOptimism, nil
  300. case "gnosis":
  301. return ChainIDGnosis, nil
  302. case "pythnet":
  303. return ChainIDPythNet, nil
  304. case "xpla":
  305. return ChainIDXpla, nil
  306. case "btc":
  307. return ChainIDBtc, nil
  308. case "base":
  309. return ChainIDBase, nil
  310. case "filecoin":
  311. return ChainIDFileCoin, nil
  312. case "sei":
  313. return ChainIDSei, nil
  314. case "rootstock":
  315. return ChainIDRootstock, nil
  316. case "scroll":
  317. return ChainIDScroll, nil
  318. case "mantle":
  319. return ChainIDMantle, nil
  320. case "blast":
  321. return ChainIDBlast, nil
  322. case "xlayer":
  323. return ChainIDXLayer, nil
  324. case "linea":
  325. return ChainIDLinea, nil
  326. case "berachain":
  327. return ChainIDBerachain, nil
  328. case "seievm":
  329. return ChainIDSeiEVM, nil
  330. case "eclipse":
  331. return ChainIDEclipse, nil
  332. case "bob":
  333. return ChainIDBOB, nil
  334. case "snaxchain":
  335. return ChainIDSnaxchain, nil
  336. case "unichain":
  337. return ChainIDUnichain, nil
  338. case "worldchain":
  339. return ChainIDWorldchain, nil
  340. case "ink":
  341. return ChainIDInk, nil
  342. case "hyperevm":
  343. return ChainIDHyperEVM, nil
  344. case "monad":
  345. return ChainIDMonad, nil
  346. case "movement":
  347. return ChainIDMovement, nil
  348. case "mezo":
  349. return ChainIDMezo, nil
  350. case "wormchain":
  351. return ChainIDWormchain, nil
  352. case "cosmoshub":
  353. return ChainIDCosmoshub, nil
  354. case "evmos":
  355. return ChainIDEvmos, nil
  356. case "kujira":
  357. return ChainIDKujira, nil
  358. case "neutron":
  359. return ChainIDNeutron, nil
  360. case "celestia":
  361. return ChainIDCelestia, nil
  362. case "stargaze":
  363. return ChainIDStargaze, nil
  364. case "seda":
  365. return ChainIDSeda, nil
  366. case "dymension":
  367. return ChainIDDymension, nil
  368. case "provenance":
  369. return ChainIDProvenance, nil
  370. case "noble":
  371. return ChainIDNoble, nil
  372. case "sepolia":
  373. return ChainIDSepolia, nil
  374. case "arbitrum_sepolia":
  375. return ChainIDArbitrumSepolia, nil
  376. case "base_sepolia":
  377. return ChainIDBaseSepolia, nil
  378. case "optimism_sepolia":
  379. return ChainIDOptimismSepolia, nil
  380. case "holesky":
  381. return ChainIDHolesky, nil
  382. case "polygon_sepolia":
  383. return ChainIDPolygonSepolia, nil
  384. default:
  385. return ChainIDUnset, fmt.Errorf("unknown chain ID: %s", s)
  386. }
  387. }
  388. func GetAllNetworkIDs() []ChainID {
  389. return []ChainID{
  390. ChainIDSolana,
  391. ChainIDEthereum,
  392. ChainIDTerra,
  393. ChainIDBSC,
  394. ChainIDPolygon,
  395. ChainIDAvalanche,
  396. ChainIDOasis,
  397. ChainIDAlgorand,
  398. ChainIDAurora,
  399. ChainIDFantom,
  400. ChainIDKarura,
  401. ChainIDAcala,
  402. ChainIDKlaytn,
  403. ChainIDCelo,
  404. ChainIDNear,
  405. ChainIDMoonbeam,
  406. ChainIDTerra2,
  407. ChainIDInjective,
  408. ChainIDOsmosis,
  409. ChainIDSui,
  410. ChainIDAptos,
  411. ChainIDArbitrum,
  412. ChainIDOptimism,
  413. ChainIDGnosis,
  414. ChainIDPythNet,
  415. ChainIDXpla,
  416. ChainIDBtc,
  417. ChainIDBase,
  418. ChainIDFileCoin,
  419. ChainIDSei,
  420. ChainIDRootstock,
  421. ChainIDScroll,
  422. ChainIDMantle,
  423. ChainIDBlast,
  424. ChainIDXLayer,
  425. ChainIDLinea,
  426. ChainIDBerachain,
  427. ChainIDSeiEVM,
  428. ChainIDEclipse,
  429. ChainIDBOB,
  430. ChainIDSnaxchain,
  431. ChainIDUnichain,
  432. ChainIDWorldchain,
  433. ChainIDInk,
  434. ChainIDHyperEVM,
  435. ChainIDMonad,
  436. ChainIDMovement,
  437. ChainIDMezo,
  438. ChainIDWormchain,
  439. ChainIDCosmoshub,
  440. ChainIDEvmos,
  441. ChainIDKujira,
  442. ChainIDNeutron,
  443. ChainIDCelestia,
  444. ChainIDStargaze,
  445. ChainIDSeda,
  446. ChainIDDymension,
  447. ChainIDProvenance,
  448. ChainIDNoble,
  449. ChainIDSepolia,
  450. ChainIDArbitrumSepolia,
  451. ChainIDBaseSepolia,
  452. ChainIDOptimismSepolia,
  453. ChainIDHolesky,
  454. ChainIDPolygonSepolia,
  455. }
  456. }
  457. // NOTE: Please keep these in numerical order.
  458. const (
  459. ChainIDUnset ChainID = 0
  460. // ChainIDSolana is the ChainID of Solana
  461. ChainIDSolana ChainID = 1
  462. // ChainIDEthereum is the ChainID of Ethereum
  463. ChainIDEthereum ChainID = 2
  464. // ChainIDTerra is the ChainID of Terra
  465. ChainIDTerra ChainID = 3
  466. // ChainIDBSC is the ChainID of Binance Smart Chain
  467. ChainIDBSC ChainID = 4
  468. // ChainIDPolygon is the ChainID of Polygon
  469. ChainIDPolygon ChainID = 5
  470. // ChainIDAvalanche is the ChainID of Avalanche
  471. ChainIDAvalanche ChainID = 6
  472. // ChainIDOasis is the ChainID of Oasis
  473. ChainIDOasis ChainID = 7
  474. // ChainIDAlgorand is the ChainID of Algorand
  475. ChainIDAlgorand ChainID = 8
  476. // ChainIDAurora is the ChainID of Aurora
  477. ChainIDAurora ChainID = 9
  478. // ChainIDFantom is the ChainID of Fantom
  479. ChainIDFantom ChainID = 10
  480. // ChainIDKarura is the ChainID of Karura
  481. ChainIDKarura ChainID = 11
  482. // ChainIDAcala is the ChainID of Acala
  483. ChainIDAcala ChainID = 12
  484. // ChainIDKlaytn is the ChainID of Klaytn
  485. ChainIDKlaytn ChainID = 13
  486. // ChainIDCelo is the ChainID of Celo
  487. ChainIDCelo ChainID = 14
  488. // ChainIDNear is the ChainID of Near
  489. ChainIDNear ChainID = 15
  490. // ChainIDMoonbeam is the ChainID of Moonbeam
  491. ChainIDMoonbeam ChainID = 16
  492. // OBSOLETE: ChainIDNeon ChainID = 17
  493. // ChainIDTerra2 is the ChainID of Terra 2
  494. ChainIDTerra2 ChainID = 18
  495. // ChainIDInjective is the ChainID of Injective
  496. ChainIDInjective ChainID = 19
  497. // ChainIDOsmosis is the ChainID of Osmosis
  498. ChainIDOsmosis ChainID = 20
  499. // ChainIDSui is the ChainID of Sui
  500. ChainIDSui ChainID = 21
  501. // ChainIDAptos is the ChainID of Aptos
  502. ChainIDAptos ChainID = 22
  503. // ChainIDArbitrum is the ChainID of Arbitrum
  504. ChainIDArbitrum ChainID = 23
  505. // ChainIDOptimism is the ChainID of Optimism
  506. ChainIDOptimism ChainID = 24
  507. // ChainIDGnosis is the ChainID of Gnosis
  508. ChainIDGnosis ChainID = 25
  509. // ChainIDPythNet is the ChainID of PythNet
  510. ChainIDPythNet ChainID = 26
  511. // NOTE: 27 belongs to a chain that was never deployed.
  512. // ChainIDXpla is the ChainID of Xpla
  513. ChainIDXpla ChainID = 28
  514. //ChainIDBtc is the ChainID of Bitcoin
  515. ChainIDBtc ChainID = 29
  516. // ChainIDBase is the ChainID of Base
  517. ChainIDBase ChainID = 30
  518. // ChainIDFileCoin is the ChainID of FileCoin
  519. ChainIDFileCoin ChainID = 31
  520. // ChainIDSei is the ChainID of Sei
  521. ChainIDSei ChainID = 32
  522. // ChainIDRootstock is the ChainID of Rootstock
  523. ChainIDRootstock ChainID = 33
  524. // ChainIDScroll is the ChainID of Scroll
  525. ChainIDScroll ChainID = 34
  526. // ChainIDMantle is the ChainID of Mantle
  527. ChainIDMantle ChainID = 35
  528. // ChainIDBlast is the ChainID of Blast
  529. ChainIDBlast ChainID = 36
  530. // ChainIDXLayer is the ChainID of XLayer
  531. ChainIDXLayer ChainID = 37
  532. // ChainIDLinea is the ChainID of Linea
  533. ChainIDLinea ChainID = 38
  534. // ChainIDBerachain is the ChainID of Berachain
  535. ChainIDBerachain ChainID = 39
  536. // ChainIDSeiEVM is the ChainID of SeiEVM
  537. ChainIDSeiEVM ChainID = 40
  538. // ChainIDEclipse is the ChainID of Eclipse
  539. ChainIDEclipse ChainID = 41
  540. // ChainIDBOB is the ChainID of BOB
  541. ChainIDBOB ChainID = 42
  542. // ChainIDSnaxchain is the ChainID of Snaxchain
  543. ChainIDSnaxchain ChainID = 43
  544. // ChainIDUnichain is the ChainID of Unichain
  545. ChainIDUnichain ChainID = 44
  546. // ChainIDWorldchain is the ChainID of Worldchain
  547. ChainIDWorldchain ChainID = 45
  548. // ChainIDInk is the ChainID of Ink
  549. ChainIDInk ChainID = 46
  550. // ChainIDHyperEVM is the ChainID of HyperEVM
  551. ChainIDHyperEVM ChainID = 47
  552. // ChainIDMonad is the ChainID of Monad
  553. ChainIDMonad ChainID = 48
  554. // ChainIDMovement is the ChainID of Movement
  555. ChainIDMovement ChainID = 49
  556. // ChainIDMezo is the ChainID of Mezo
  557. ChainIDMezo ChainID = 50
  558. //ChainIDWormchain is the ChainID of Wormchain
  559. // Wormchain is in it's own range.
  560. ChainIDWormchain ChainID = 3104
  561. // The IBC chains start at 4000.
  562. // ChainIDCosmoshub is the ChainID of Cosmoshub
  563. ChainIDCosmoshub ChainID = 4000
  564. // ChainIDEvmos is the ChainID of Evmos
  565. ChainIDEvmos ChainID = 4001
  566. // ChainIDKujira is the ChainID of Kujira
  567. ChainIDKujira ChainID = 4002
  568. // ChainIDNeutron is the ChainID of Neutron
  569. ChainIDNeutron ChainID = 4003
  570. // ChainIDCelestia is the ChainID of Celestia
  571. ChainIDCelestia ChainID = 4004
  572. // ChainIDStargaze is the ChainID of Stargaze
  573. ChainIDStargaze ChainID = 4005
  574. // ChainIDSeda is the ChainID of Seda
  575. ChainIDSeda ChainID = 4006
  576. // ChainIDDymension is the ChainID of Dymension
  577. ChainIDDymension ChainID = 4007
  578. // ChainIDProvenance is the ChainID of Provenance
  579. ChainIDProvenance ChainID = 4008
  580. // ChainIDNoble is the ChainID of Noble
  581. ChainIDNoble ChainID = 4009
  582. // ChainIDSepolia is the ChainID of Sepolia
  583. // The Testnet only chains start at 10000.
  584. ChainIDSepolia ChainID = 10002
  585. // ChainIDArbitrumSepolia is the ChainID of Arbitrum on Sepolia
  586. ChainIDArbitrumSepolia ChainID = 10003
  587. // ChainIDBaseSepolia is the ChainID of Base on Sepolia
  588. ChainIDBaseSepolia ChainID = 10004
  589. // ChainIDOptimismSepolia is the ChainID of Optimism on Sepolia
  590. ChainIDOptimismSepolia ChainID = 10005
  591. // ChainIDHolesky is the ChainID of Holesky
  592. ChainIDHolesky ChainID = 10006
  593. // ChainIDPolygonSepolia is the ChainID of Polygon on Sepolia
  594. ChainIDPolygonSepolia ChainID = 10007
  595. // OBSOLETE: ChainIDMonadDevnet ChainID = 10008
  596. // Minimum VAA size is derrived from the following assumptions:
  597. // HEADER
  598. // - Supported VAA Version (1 byte)
  599. // - Guardian Set Index (4 bytes)
  600. // - Length of Signatures (1 byte) <== assume no signatures
  601. // - Actual Signatures (0 bytes)
  602. // BODY
  603. // - timestamp (4 bytes)
  604. // - nonce (4 bytes)
  605. // - emitter chain (2 bytes)
  606. // - emitter address (32 bytes)
  607. // - sequence (8 bytes)
  608. // - consistency level (1 byte)
  609. // - payload (0 bytes)
  610. // BATCH
  611. // - Length of Observation Hashes (1 byte) <== minimum one
  612. // - Observation Hash (32 bytes)
  613. // - Length of Observations (1 byte) <== minimum one
  614. // - Observation Index (1 byte)
  615. // - Observation Length (1 byte)
  616. // - Observation, aka BODY, aka Headless (51 bytes)
  617. // From Above:
  618. // HEADER: 1 + 4 + 1 + 0 = 6
  619. // BODY: 4 + 4 + 2 + 32 + 8 + 1 + 0 = 51
  620. // BATCH: 1 + 32 + 1 + 1 + 1 + 51 = 88
  621. //
  622. // More details here: https://docs.wormholenetwork.com/wormhole/vaas
  623. minHeadlessVAALength = 51 // HEADER
  624. minVAALength = 57 // HEADER + BODY
  625. SupportedVAAVersion = 0x01
  626. )
  627. // UnmarshalBody deserializes the binary representation of a VAA's "BODY" properties
  628. // The BODY fields are common among multiple types of VAA - v1, v2, etc
  629. func UnmarshalBody(data []byte, reader *bytes.Reader, v *VAA) (*VAA, error) {
  630. unixSeconds := uint32(0)
  631. if err := binary.Read(reader, binary.BigEndian, &unixSeconds); err != nil {
  632. return nil, fmt.Errorf("failed to read timestamp: %w", err)
  633. }
  634. v.Timestamp = time.Unix(int64(unixSeconds), 0)
  635. if err := binary.Read(reader, binary.BigEndian, &v.Nonce); err != nil {
  636. return nil, fmt.Errorf("failed to read nonce: %w", err)
  637. }
  638. if err := binary.Read(reader, binary.BigEndian, &v.EmitterChain); err != nil {
  639. return nil, fmt.Errorf("failed to read emitter chain: %w", err)
  640. }
  641. emitterAddress := Address{}
  642. if n, err := reader.Read(emitterAddress[:]); err != nil || n != 32 {
  643. return nil, fmt.Errorf("failed to read emitter address [%d]: %w", n, err)
  644. }
  645. v.EmitterAddress = emitterAddress
  646. if err := binary.Read(reader, binary.BigEndian, &v.Sequence); err != nil {
  647. return nil, fmt.Errorf("failed to read sequence: %w", err)
  648. }
  649. if err := binary.Read(reader, binary.BigEndian, &v.ConsistencyLevel); err != nil {
  650. return nil, fmt.Errorf("failed to read commitment: %w", err)
  651. }
  652. // Make sure to only read the payload if the VAA has one; VAAs may have a 0 length payload
  653. if reader.Len() != 0 {
  654. payload := make([]byte, reader.Len())
  655. n, err := reader.Read(payload)
  656. if err != nil {
  657. return nil, fmt.Errorf("failed to read payload [%d]: %w", n, err)
  658. }
  659. v.Payload = payload[:n]
  660. } else {
  661. v.Payload = []byte{}
  662. }
  663. return v, nil
  664. }
  665. // Unmarshal deserializes the binary representation of a VAA
  666. func Unmarshal(data []byte) (*VAA, error) {
  667. if len(data) < minVAALength {
  668. return nil, fmt.Errorf("VAA is too short")
  669. }
  670. v := &VAA{}
  671. v.Version = data[0]
  672. if v.Version != SupportedVAAVersion {
  673. return nil, fmt.Errorf("unsupported VAA version: %d", v.Version)
  674. }
  675. reader := bytes.NewReader(data[1:])
  676. if err := binary.Read(reader, binary.BigEndian, &v.GuardianSetIndex); err != nil {
  677. return nil, fmt.Errorf("failed to read guardian set index: %w", err)
  678. }
  679. lenSignatures, er := reader.ReadByte()
  680. if er != nil {
  681. return nil, fmt.Errorf("failed to read signature length")
  682. }
  683. v.Signatures = make([]*Signature, lenSignatures)
  684. for i := 0; i < int(lenSignatures); i++ {
  685. index, err := reader.ReadByte()
  686. if err != nil {
  687. return nil, fmt.Errorf("failed to read validator index [%d]", i)
  688. }
  689. signature := [65]byte{}
  690. if n, err := reader.Read(signature[:]); err != nil || n != 65 {
  691. return nil, fmt.Errorf("failed to read signature [%d]: %w", i, err)
  692. }
  693. v.Signatures[i] = &Signature{
  694. Index: index,
  695. Signature: signature,
  696. }
  697. }
  698. return UnmarshalBody(data, reader, v)
  699. }
  700. // signingBody returns the binary representation of the data that is relevant for signing and verifying the VAA
  701. func (v *VAA) signingBody() []byte {
  702. return v.serializeBody()
  703. }
  704. func doubleKeccak(bz []byte) common.Hash {
  705. // In order to save space in the solana signature verification instruction, we hash twice so we only need to pass in
  706. // the first hash (32 bytes) vs the full body data.
  707. return crypto.Keccak256Hash(crypto.Keccak256Hash(bz).Bytes())
  708. }
  709. // This is a temporary method to produce a vaa signing digest on raw bytes.
  710. // It is error prone and we should use `v.SigningDigest()` instead.
  711. // whenever possible.
  712. // This will be removed in a subsequent release.
  713. func DeprecatedSigningDigest(bz []byte) common.Hash {
  714. return doubleKeccak(bz)
  715. }
  716. // MessageSigningDigest returns the hash of the data prepended with it's signing prefix.
  717. // This is intending to be used for signing messages of different types from VAA's.
  718. // The message prefix helps protect from message collisions.
  719. func MessageSigningDigest(prefix []byte, data []byte) (common.Hash, error) {
  720. if len(prefix) < 32 {
  721. // Prefixes must be at least 32 bytes
  722. // https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0009_guardian_key.md
  723. return common.Hash([32]byte{}), errors.New("prefix must be at least 32 bytes")
  724. }
  725. return crypto.Keccak256Hash(prefix[:], data), nil
  726. }
  727. // SigningDigest returns the hash of the vaa hash to be signed directly.
  728. // This is used for signature generation and verification
  729. func (v *VAA) SigningDigest() common.Hash {
  730. return doubleKeccak(v.signingBody())
  731. }
  732. // Verify Signature checks that the provided address matches the address that created the signature for the provided digest
  733. // Digest should be the output of SigningMsg(data).Bytes()
  734. // Should not be public as other message types should be verified using a message prefix.
  735. func verifySignature(vaa_digest []byte, signature *Signature, address common.Address) bool {
  736. // retrieve the address that signed the data
  737. pubKey, err := crypto.Ecrecover(vaa_digest, signature.Signature[:])
  738. if err != nil {
  739. return false
  740. }
  741. addr := common.BytesToAddress(crypto.Keccak256(pubKey[1:])[12:])
  742. // check that the recovered address equals the provided address
  743. return addr == address
  744. }
  745. // Digest should be the output of SigningMsg(data).Bytes()
  746. // Should not be public as other message types should be verified using a message prefix.
  747. func verifySignatures(vaa_digest []byte, signatures []*Signature, addresses []common.Address) bool {
  748. if len(addresses) < len(signatures) {
  749. return false
  750. }
  751. last_index := -1
  752. signing_addresses := []common.Address{}
  753. for _, sig := range signatures {
  754. if int(sig.Index) >= len(addresses) {
  755. return false
  756. }
  757. // Ensure increasing indexes
  758. if int(sig.Index) <= last_index {
  759. return false
  760. }
  761. last_index = int(sig.Index)
  762. // verify this signature
  763. addr := addresses[sig.Index]
  764. ok := verifySignature(vaa_digest, sig, addr)
  765. if !ok {
  766. return false
  767. }
  768. // Ensure we never see the same signer twice
  769. for _, signing_address := range signing_addresses {
  770. if signing_address == addr {
  771. return false
  772. }
  773. }
  774. signing_addresses = append(signing_addresses, addr)
  775. }
  776. return true
  777. }
  778. // Operating on bytes directly is error prone. We should use `vaa.VerifyingSignatures()` whenever possible.
  779. // This function will be removed in a subsequent release.
  780. func DeprecatedVerifySignatures(vaaBody []byte, signatures []*Signature, addresses []common.Address) bool {
  781. vaaDigest := doubleKeccak(vaaBody)
  782. return verifySignatures(vaaDigest[:], signatures, addresses)
  783. }
  784. func VerifyMessageSignature(prefix []byte, messageBody []byte, signatures *Signature, addresses common.Address) bool {
  785. if len(prefix) < 32 {
  786. return false
  787. }
  788. msgDigest, err := MessageSigningDigest(prefix, messageBody)
  789. if err != nil {
  790. return false
  791. }
  792. return verifySignature(msgDigest[:], signatures, addresses)
  793. }
  794. // VerifySignatures verifies the signature of the VAA given the signer addresses.
  795. // Returns true if the signatures were verified successfully.
  796. func (v *VAA) VerifySignatures(addresses []common.Address) bool {
  797. return verifySignatures(v.SigningDigest().Bytes(), v.Signatures, addresses)
  798. }
  799. // Verify is a function on the VAA that takes a complete set of guardian keys as input and attempts certain checks with respect to this guardian.
  800. // Verify will return nil if the VAA passes checks. Otherwise, Verify will return an error containing the text of the first check to fail.
  801. // NOTE: Verify will not work correctly if a subset of the guardian set keys is passed in. The complete guardian set must be passed in.
  802. // Verify does the following checks:
  803. // - If the guardian does not have or know its own guardian set keys, then the VAA cannot be verified.
  804. // - Quorum is calculated on the guardian set passed in and checks if the VAA has enough signatures.
  805. // - The signatures in the VAA is verified against the guardian set keys.
  806. func (v *VAA) Verify(addresses []common.Address) error {
  807. if addresses == nil {
  808. return errors.New("no addresses were provided")
  809. }
  810. // Check if VAA doesn't have any signatures
  811. if len(v.Signatures) == 0 {
  812. return errors.New("VAA was not signed")
  813. }
  814. // Verify VAA has enough signatures for quorum
  815. quorum := CalculateQuorum(len(addresses))
  816. if len(v.Signatures) < quorum {
  817. return errors.New("VAA did not have a quorum")
  818. }
  819. // Verify VAA signatures to prevent a DoS attack on our local store.
  820. if !v.VerifySignatures(addresses) {
  821. return errors.New("VAA had bad signatures")
  822. }
  823. return nil
  824. }
  825. // Marshal returns the binary representation of the VAA
  826. func (v *VAA) Marshal() ([]byte, error) {
  827. buf := new(bytes.Buffer)
  828. MustWrite(buf, binary.BigEndian, v.Version)
  829. MustWrite(buf, binary.BigEndian, v.GuardianSetIndex)
  830. // Write signatures
  831. MustWrite(buf, binary.BigEndian, uint8(len(v.Signatures)))
  832. for _, sig := range v.Signatures {
  833. MustWrite(buf, binary.BigEndian, sig.Index)
  834. buf.Write(sig.Signature[:])
  835. }
  836. // Write Body
  837. buf.Write(v.serializeBody())
  838. return buf.Bytes(), nil
  839. }
  840. // implement encoding.BinaryMarshaler interface for the VAA struct
  841. func (v VAA) MarshalBinary() ([]byte, error) {
  842. return v.Marshal()
  843. }
  844. // implement encoding.BinaryUnmarshaler interface for the VAA struct
  845. func (v *VAA) UnmarshalBinary(data []byte) error {
  846. vaa, err := Unmarshal(data)
  847. if err != nil {
  848. return err
  849. }
  850. // derefernce the stuct created by Unmarshal, and assign it to the method's context
  851. *v = *vaa
  852. return nil
  853. }
  854. // MessageID returns a human-readable emitter_chain/emitter_address/sequence tuple.
  855. func (v *VAA) MessageID() string {
  856. return fmt.Sprintf("%d/%s/%d", v.EmitterChain, v.EmitterAddress, v.Sequence)
  857. }
  858. // UniqueID normalizes the ID of the VAA (any type) for the Attestation interface
  859. // UniqueID returns the MessageID that uniquely identifies the Attestation
  860. func (v *VAA) UniqueID() string {
  861. return v.MessageID()
  862. }
  863. // HexDigest returns the hex-encoded digest.
  864. func (v *VAA) HexDigest() string {
  865. return hex.EncodeToString(v.SigningDigest().Bytes())
  866. }
  867. /*
  868. SECURITY: Do not change this code! Changing it could result in two different hashes for
  869. the same observation. But xDapps rely on the hash of an observation for replay protection.
  870. */
  871. func (v *VAA) serializeBody() []byte {
  872. buf := new(bytes.Buffer)
  873. MustWrite(buf, binary.BigEndian, uint32(v.Timestamp.Unix()))
  874. MustWrite(buf, binary.BigEndian, v.Nonce)
  875. MustWrite(buf, binary.BigEndian, v.EmitterChain)
  876. buf.Write(v.EmitterAddress[:])
  877. MustWrite(buf, binary.BigEndian, v.Sequence)
  878. MustWrite(buf, binary.BigEndian, v.ConsistencyLevel)
  879. buf.Write(v.Payload)
  880. return buf.Bytes()
  881. }
  882. func (v *VAA) AddSignature(key *ecdsa.PrivateKey, index uint8) {
  883. sig, err := crypto.Sign(v.SigningDigest().Bytes(), key)
  884. if err != nil {
  885. panic(err)
  886. }
  887. sigData := [65]byte{}
  888. copy(sigData[:], sig)
  889. v.Signatures = append(v.Signatures, &Signature{
  890. Index: index,
  891. Signature: sigData,
  892. })
  893. }
  894. // NOTE: This function assumes that the caller has verified that the VAA is from the token bridge.
  895. func IsTransfer(payload []byte) bool {
  896. return (len(payload) > 0) && ((payload[0] == 1) || (payload[0] == 3))
  897. }
  898. func DecodeTransferPayloadHdr(payload []byte) (*TransferPayloadHdr, error) {
  899. if !IsTransfer(payload) {
  900. return nil, fmt.Errorf("unsupported payload type")
  901. }
  902. if len(payload) < 101 {
  903. return nil, fmt.Errorf("buffer too short")
  904. }
  905. p := &TransferPayloadHdr{}
  906. // Payload type: payload[0]
  907. p.Type = uint8(payload[0])
  908. // Amount: payload[1] for 32
  909. p.Amount = new(big.Int)
  910. p.Amount.SetBytes(payload[1:33])
  911. reader := bytes.NewReader(payload[33:])
  912. // Origin address: payload[33] for 32
  913. err := binary.Read(reader, binary.BigEndian, &p.OriginAddress)
  914. if err != nil {
  915. return nil, err
  916. }
  917. // Origin chain ID: payload[65] for 2
  918. err = binary.Read(reader, binary.BigEndian, &p.OriginChain)
  919. if err != nil {
  920. return nil, err
  921. }
  922. // Target address: payload[67] for 32
  923. err = binary.Read(reader, binary.BigEndian, &p.TargetAddress)
  924. if err != nil {
  925. return nil, err
  926. }
  927. // Target chain ID: payload[99] for 2
  928. err = binary.Read(reader, binary.BigEndian, &p.TargetChain)
  929. if err != nil {
  930. return nil, err
  931. }
  932. return p, nil
  933. }
  934. // GetEmitterChain implements the processor.Observation interface for *VAA.
  935. func (v *VAA) GetEmitterChain() ChainID {
  936. return v.EmitterChain
  937. }
  938. // MustWrite calls binary.Write and panics on errors
  939. func MustWrite(w io.Writer, order binary.ByteOrder, data interface{}) {
  940. if err := binary.Write(w, order, data); err != nil {
  941. panic(fmt.Errorf("failed to write binary data: %v", data).Error())
  942. }
  943. }
  944. // StringToAddress converts a hex-encoded address into a vaa.Address
  945. func StringToAddress(value string) (Address, error) {
  946. var address Address
  947. // Make sure we have enough to decode
  948. if len(value) < 2 {
  949. return address, fmt.Errorf("value must be at least 1 byte")
  950. }
  951. // Trim any preceding "0x" to the address
  952. value = strings.TrimPrefix(value, "0x")
  953. // Decode the string from hex to binary
  954. res, err := hex.DecodeString(value)
  955. if err != nil {
  956. return address, err
  957. }
  958. // Make sure we don't have too many bytes
  959. if len(res) > 32 {
  960. return address, fmt.Errorf("value must be no more than 32 bytes")
  961. }
  962. copy(address[32-len(res):], res)
  963. return address, nil
  964. }
  965. func BytesToAddress(b []byte) (Address, error) {
  966. var address Address
  967. if len(b) > 32 {
  968. return address, fmt.Errorf("value must be no more than 32 bytes")
  969. }
  970. copy(address[32-len(b):], b)
  971. return address, nil
  972. }
  973. // StringToHash converts a hex-encoded string into a common.Hash
  974. func StringToHash(value string) (common.Hash, error) {
  975. var tx common.Hash
  976. // Make sure we have enough to decode
  977. if len(value) < 2 {
  978. return tx, fmt.Errorf("value must be at least 1 byte")
  979. }
  980. // Trim any preceding "0x" to the address
  981. value = strings.TrimPrefix(value, "0x")
  982. res, err := hex.DecodeString(value)
  983. if err != nil {
  984. return tx, err
  985. }
  986. tx = common.BytesToHash(res)
  987. return tx, nil
  988. }
  989. func BytesToHash(b []byte) (common.Hash, error) {
  990. var hash common.Hash
  991. if len(b) > 32 {
  992. return hash, fmt.Errorf("value must be no more than 32 bytes")
  993. }
  994. hash = common.BytesToHash(b)
  995. return hash, nil
  996. }