Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solana deployment scripts and module configs #671

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions .github/workflows/cross-chain-solana.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: Cross-chain Solana

on:
schedule:
- cron: "0 0 * * *"
push:
branches:
- main
paths:
- "cross-chain/solana/**"
- ".github/workflows/cross-chain-solana.yml"
pull_request:

jobs:
contracts-detect-changes:
runs-on: ubuntu-latest
outputs:
path-filter: ${{ steps.filter.outputs.path-filter }}
steps:
- uses: actions/checkout@v3
if: github.event_name == 'pull_request'

- uses: dorny/paths-filter@v2
if: github.event_name == 'pull_request'
id: filter
with:
filters: |
path-filter:
- './cross-chain/solana/**'
- './.github/workflows/cross-chain-solana.yml'

contracts-build-and-test:
needs: contracts-detect-changes
if: |
github.event_name != 'pull_request'
|| needs.contracts-detect-changes.outputs.path-filter == 'true'
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./cross-chain/solana
steps:
- uses: actions/checkout@v3

- uses: actions/setup-node@v3
with:
node-version: "16.x"
cache: "yarn"
cache-dependency-path: cross-chain/solana/yarn.lock

# A workaround for transitive dependencies that use the obsolete git://
# prefix instead of the recommended https://
- name: Configure git to not use unauthenticated protocol
run: git config --global url."https://".insteadOf git://

- name: Install Solana
run: |
sh -c "$(curl -sSfL https://release.solana.com/v1.16.5/install)"
export PATH="/home/runner/.local/share/solana/install/active_release/bin:$PATH"

- name: Install Rust
run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y

- name: Install Anchor
run: |
cargo install --git https://github.com/coral-xyz/anchor --tag v0.28.0 anchor-cli --locked

- name: Install dependencies
run: yarn install

- name: Anchor build
run: |
export PATH="/home/runner/.local/share/solana/install/active_release/bin:$PATH"
yarn build

# There is problem with a `solana-keygen new` command. The workaround is to create a keyfile manually just for testing purposes.
- name: Run tests
run: |
export PATH="/home/runner/.local/share/solana/install/active_release/bin:$PATH"
solana config set -u localhost
echo "[132,196,51,204,234,79,135,213,169,81,250,90,73,168,28,41,193,49,153,71,192,44,228,74,230,78,211,95,54,241,137,50,119,155,54,147,229,137,197,57,146,111,140,177,222,54,120,254,254,250,191,135,251,47,163,16,180,160,110,108,54,111,84,76]" >> ~/.config/solana/id.json
yarn test

contracts-format:
needs: contracts-detect-changes
if: |
github.event_name == 'push'
|| needs.contracts-detect-changes.outputs.path-filter == 'true'
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./cross-chain/solana
steps:
- uses: actions/checkout@v3

- uses: actions/setup-node@v3
with:
node-version: "16.x"
cache: "yarn"
cache-dependency-path: cross-chain/solana/yarn.lock

# A workaround for transitive dependencies that use the obsolete git://
# prefix instead of the recommended https://
- name: Configure git to not use unauthenticated protocol
run: git config --global url."https://".insteadOf git://

- name: Install dependencies
run: yarn install

- name: Check formatting
run: yarn format
1 change: 1 addition & 0 deletions cross-chain/solana/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ target
node_modules
test-ledger
.yarn
solana.env
3 changes: 3 additions & 0 deletions cross-chain/solana/.prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
...require("@thesis-co/prettier-config"),
}
79 changes: 70 additions & 9 deletions cross-chain/solana/migrations/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,73 @@
// 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.
anchor.setProvider(provider);
dotenv.config({ path: "../solana.env" })

anchor.setProvider(provider)

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 minterKeys = loadKey(process.env.MINTER_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()

const [minterInfoPDA] = web3.PublicKey.findProgramAddressSync(
[
anchor.utils.bytes.utf8.encode("minter-info"),
tbtcKeys.publicKey.toBuffer(),
minterKeys.publicKey.toBuffer(),
],
program.programId
)

// add minter keys (minterKeys is the wormholeGateway-keypair)
await program.methods
.addMinter()
.accounts({
tbtc: tbtcKeys.publicKey,
authority: authority.publicKey,
minter: minterKeys.publicKey,
payer: authority.publicKey,
minterInfo: minterInfoPDA,
})
.signers([minterKeys])
.rpc()

// add a guardian?

// update mappings (self, arbitrum, optimism, polygon)
}

function loadKey(filename: string): Keypair {
try {
const contents = fs.readFileSync(filename).toString()
const bs = Uint8Array.from(JSON.parse(contents))

// Add your deploy script here.
};
return Keypair.fromSecretKey(bs)
} catch {
console.log("Unable to read keypair...", filename)
}
}
19 changes: 14 additions & 5 deletions cross-chain/solana/package.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
{
{
"name": "@keep-network/tbtc-v2-solana",
"version": "1.0.0-dev",
"description": "tBTC v2 on Solana",
"license": "GPL-3.0-only",
"scripts": {
"build": "anchor build",
"format": "npm run lint",
"format:fix": "npm run lint:fix",
"lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w",
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
},
"dependencies": {
"@coral-xyz/anchor": "^0.28.0"
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check",
"test": "anchor test"
},
"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",
"@thesis-co/eslint-config": "github:thesis/eslint-config",
"dotenv": "^16.3.1",
"chai": "^4.3.4",
"mocha": "^9.0.3",
"prettier": "^2.6.2",
Expand Down
72 changes: 72 additions & 0 deletions cross-chain/solana/scripts/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/bin/bash
set -eo pipefail

help() {
echo -e "\nUsage: $0 --cluster <cluster>"

echo -e "\nCommand line arguments:\n"
echo -e "\t--cluster: <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
exit 1
}

[ -z "$TBTC_KEYS" ] && {
echo "'WALLET' env var is not set" >&2
exit 1
}

[ -z "$MINTER_KEYS" ] && {
echo "'MINTER_KEYS' env var is not set" >&2
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
5 changes: 5 additions & 0 deletions cross-chain/solana/scripts/transfer_authority.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
set -eo pipefail

# TODO: transfer upgrade authority to Threshold Council multisig
solana program set-upgrade-authority -k <current_keypair_path> <programID> --new-upgrade-authority <pubkey>
4 changes: 4 additions & 0 deletions cross-chain/solana/solana.env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
WALLET=<path>
TBTC_KEYS=<path>
MINTER_KEYS=<path>
UPGRADE_AUTHORITY=<threshold_council_multisig>
Loading