terra.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import {
  2. Coin,
  3. Fee,
  4. LCDClient,
  5. MnemonicKey,
  6. MsgExecuteContract,
  7. } from "@terra-money/terra.js";
  8. import { fromUint8Array } from "js-base64";
  9. import { impossible, Payload } from "./vaa";
  10. import { NETWORKS } from "./networks";
  11. import axios from "axios";
  12. import { CONTRACTS, TerraChainName } from "@certusone/wormhole-sdk/lib/cjs/utils/consts";
  13. export async function execute_terra(
  14. payload: Payload,
  15. vaa: Buffer,
  16. network: "MAINNET" | "TESTNET" | "DEVNET",
  17. chain: TerraChainName
  18. ) {
  19. let n = NETWORKS[network][chain];
  20. let contracts = CONTRACTS[network][chain];
  21. const terra = new LCDClient({
  22. URL: n.rpc,
  23. chainID: n.chain_id,
  24. isClassic: chain === "terra",
  25. });
  26. const wallet = terra.wallet(
  27. new MnemonicKey({
  28. mnemonic: n.key,
  29. })
  30. );
  31. let target_contract: string;
  32. let execute_msg: object;
  33. switch (payload.module) {
  34. case "Core":
  35. target_contract = contracts.core;
  36. // sigh...
  37. execute_msg = {
  38. submit_v_a_a: {
  39. vaa: fromUint8Array(vaa),
  40. },
  41. };
  42. switch (payload.type) {
  43. case "GuardianSetUpgrade":
  44. console.log("Submitting new guardian set");
  45. break;
  46. case "ContractUpgrade":
  47. console.log("Upgrading core contract");
  48. break;
  49. default:
  50. impossible(payload);
  51. }
  52. break;
  53. case "NFTBridge":
  54. if (contracts.nft_bridge === undefined) {
  55. // NOTE: this code can safely be removed once the terra NFT bridge is
  56. // released, but it's fine for it to stay, as the condition will just be
  57. // skipped once 'contracts.nft_bridge' is defined
  58. throw new Error("NFT bridge not supported yet for terra");
  59. }
  60. target_contract = contracts.nft_bridge;
  61. execute_msg = {
  62. submit_vaa: {
  63. data: fromUint8Array(vaa),
  64. },
  65. };
  66. switch (payload.type) {
  67. case "ContractUpgrade":
  68. console.log("Upgrading contract");
  69. break;
  70. case "RegisterChain":
  71. console.log("Registering chain");
  72. break;
  73. case "Transfer":
  74. console.log("Completing transfer");
  75. break;
  76. default:
  77. impossible(payload);
  78. }
  79. break;
  80. case "TokenBridge":
  81. target_contract = contracts.token_bridge;
  82. execute_msg = {
  83. submit_vaa: {
  84. data: fromUint8Array(vaa),
  85. },
  86. };
  87. switch (payload.type) {
  88. case "ContractUpgrade":
  89. console.log("Upgrading contract");
  90. break;
  91. case "RegisterChain":
  92. console.log("Registering chain");
  93. break;
  94. case "Transfer":
  95. console.log("Completing transfer");
  96. break;
  97. case "AttestMeta":
  98. console.log("Creating wrapped token");
  99. break;
  100. case "TransferWithPayload":
  101. throw Error("Can't complete payload 3 transfer from CLI");
  102. default:
  103. impossible(payload);
  104. break;
  105. }
  106. break;
  107. default:
  108. target_contract = impossible(payload);
  109. execute_msg = impossible(payload);
  110. }
  111. const transaction = new MsgExecuteContract(
  112. wallet.key.accAddress,
  113. target_contract,
  114. execute_msg,
  115. { uluna: 1000 }
  116. );
  117. const feeDenoms = ["uluna"];
  118. const gasPrices = await axios
  119. .get("https://fcd.terra.dev/v1/txs/gas_prices")
  120. .then((result) => result.data);
  121. const feeEstimate = await terra.tx.estimateFee(
  122. [
  123. {
  124. sequenceNumber: await wallet.sequence(),
  125. publicKey: wallet.key.publicKey,
  126. },
  127. ],
  128. {
  129. msgs: [transaction],
  130. memo: "",
  131. feeDenoms,
  132. gasPrices,
  133. }
  134. );
  135. wallet
  136. .createAndSignTx({
  137. msgs: [transaction],
  138. memo: "",
  139. fee: new Fee(
  140. feeEstimate.gas_limit,
  141. feeEstimate.amount.add(new Coin("uluna", 12))
  142. ),
  143. })
  144. .then((tx) => terra.tx.broadcast(tx))
  145. .then((result) => {
  146. console.log(result);
  147. console.log(`TX hash: ${result.txhash}`);
  148. });
  149. }