From 8320f27deb742eecc5325618534ece13c2022c4e Mon Sep 17 00:00:00 2001 From: Dmitry Date: Sat, 22 Jul 2023 18:07:17 +0200 Subject: [PATCH] Drafting deployment script and instructions The plan is to use deploy.sh script to deploy programs on Solana and use a migration script to execute required instructions on the deployed programs. --- cross-chain/solana/.gitignore | 1 + cross-chain/solana/deploy.sh | 64 +++++++++++++++++++++++++ cross-chain/solana/migrations/deploy.ts | 57 +++++++++++++++++++--- cross-chain/solana/package.json | 6 +-- cross-chain/solana/solana.env.template | 3 ++ 5 files changed, 121 insertions(+), 10 deletions(-) create mode 100755 cross-chain/solana/deploy.sh create mode 100644 cross-chain/solana/solana.env.template diff --git a/cross-chain/solana/.gitignore b/cross-chain/solana/.gitignore index 8d401163f..8ab586cef 100644 --- a/cross-chain/solana/.gitignore +++ b/cross-chain/solana/.gitignore @@ -6,3 +6,4 @@ target node_modules test-ledger .yarn +solana.env diff --git a/cross-chain/solana/deploy.sh b/cross-chain/solana/deploy.sh new file mode 100755 index 000000000..73a30218d --- /dev/null +++ b/cross-chain/solana/deploy.sh @@ -0,0 +1,64 @@ +#!/bin/bash +set -eo pipefail + +help() { + echo -e "\nUsage: $0 --cluster " + + echo -e "\nCommand line arguments:\n" + echo -e "\t--cluster: \n" \ + "\t\tAvailable deployment clusters: 'mainnet-beta', 'devnet', and 'localnet'." \ + "Overrides a cluster set in Anchor.toml" + exit 1 # Exit script after printing help +} + +# Setting env variables in the current bash shell +source solana.env + +# Transform long options to short ones +for arg in "$@"; do + shift + case "$arg" in + "--cluster") set -- "$@" "-n" ;; + "--help") set -- "$@" "-h" ;; + *) set -- "$@" "$arg" ;; + esac +done + +# Parse short options +OPTIND=1 +while getopts "n:w:h" opt; do + case "$opt" in + n) CLUSTER="$OPTARG" ;; + h) help ;; + ?) help ;; # Print help in case parameter is non-existent + esac +done +shift $(expr $OPTIND - 1) # remove options from positional parameters + +[ -z "$CLUSTER" ] && { + echo "'--cluster' option not provided" >&2 + help + exit 1 +} + +[ -z "$WALLET" ] && { + echo "'WALLET' env var is not set" >&2 + help + exit 1 +} + +echo "Building workspace for cluster: $CLUSTER" +anchor build --provider.cluster $CLUSTER + +echo "Syncing the program's id ..." +anchor keys sync + +echo "Building workspace again to include new program ID in the binary ..." +anchor build --provider.cluster $CLUSTER + +echo "Deploying program(s) for cluster: $CLUSTER" +anchor deploy --provider.cluster $CLUSTER --provider.wallet $WALLET + +echo "Migrating..." +anchor migrate --provider.cluster $CLUSTER --provider.wallet $WALLET +# TODO: anchor migrate // executes migrations/deploy.ts script diff --git a/cross-chain/solana/migrations/deploy.ts b/cross-chain/solana/migrations/deploy.ts index 82fb175fa..c1b3d1a34 100644 --- a/cross-chain/solana/migrations/deploy.ts +++ b/cross-chain/solana/migrations/deploy.ts @@ -1,12 +1,55 @@ -// Migrations are an early feature. Currently, they're nothing more than this -// single deploy script that's invoked from the CLI, injecting a provider -// configured from the workspace's Anchor.toml. - -const anchor = require("@coral-xyz/anchor"); +import * as anchor from "@coral-xyz/anchor"; +import * as web3 from "@solana/web3.js"; +import fs from "fs"; +import { Keypair } from "@solana/web3.js"; +import dotenv from "dotenv"; module.exports = async function (provider) { - // Configure client to use the provider. + dotenv.config({ path: "../solana.env" }) + anchor.setProvider(provider); - // Add your deploy script here. + const program = anchor.workspace.Tbtc; + // This wallet deployed the program and is also an authority + const authority = loadKey(process.env.WALLET); + const tbtcKeys = loadKey(process.env.TBTC_KEYS); + + const [tbtcMintPDA, _] = web3.PublicKey.findProgramAddressSync( + [ + anchor.utils.bytes.utf8.encode("tbtc-mint"), + tbtcKeys.publicKey.toBuffer(), + ], + program.programId, + ); + + // Initalize tbtc program + await program.methods + .initialize() + .accounts({ + tbtcMint: tbtcMintPDA, + tbtc: tbtcKeys.publicKey, + authority: authority.publicKey, + }) + .signers([tbtcKeys]) + .rpc(); + + // add a minter (wormhole gateway (minter keys)) + + // add a guardian? + + // update mappings (self, arbitrum, optimism, polygon) + + // transfer ownership to council + // solana program set-upgrade-authority -k --new-upgrade-authority }; + +function loadKey(filename: string): Keypair { + try { + const contents = fs.readFileSync(filename).toString(); + const bs = Uint8Array.from(JSON.parse(contents)); + + return Keypair.fromSecretKey(bs); + } catch { + console.log("Unable to read keypair...", filename); + } +} diff --git a/cross-chain/solana/package.json b/cross-chain/solana/package.json index 4a866202d..28edb0dbb 100644 --- a/cross-chain/solana/package.json +++ b/cross-chain/solana/package.json @@ -3,15 +3,15 @@ "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" }, - "dependencies": { - "@coral-xyz/anchor": "^0.28.0" - }, "devDependencies": { + "@coral-xyz/anchor": "^0.28.0", "@solana/spl-token": "^0.3.8", "@solana/web3.js": "^1.77.3", "@types/bn.js": "^5.1.0", "@types/chai": "^4.3.0", "@types/mocha": "^9.0.0", + "@types/node": "^18.11.18", + "dotenv": "^16.3.1", "chai": "^4.3.4", "mocha": "^9.0.3", "prettier": "^2.6.2", diff --git a/cross-chain/solana/solana.env.template b/cross-chain/solana/solana.env.template new file mode 100644 index 000000000..e87aa3bb6 --- /dev/null +++ b/cross-chain/solana/solana.env.template @@ -0,0 +1,3 @@ +WALLET= +TBTC_KEYS= +UPGRADE_AUTHORITY= \ No newline at end of file