Skip to content

Commit

Permalink
solana draft
Browse files Browse the repository at this point in the history
  • Loading branch information
yashnevatia committed Dec 23, 2024
1 parent bc536f0 commit 79c2961
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 1 deletion.
183 changes: 183 additions & 0 deletions deployment/common/changeset/deploy_link_token_sol_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
package changeset_test

import (
"context"
"testing"

"bytes"
"fmt"
"os/exec"

// "github.com/stretchr/testify/require"
// "go.uber.org/zap/zapcore"
// "github.com/smartcontractkit/chainlink/deployment/common/changeset"
// "github.com/smartcontractkit/chainlink/deployment/environment/memory"
// "github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/gagliardetto/solana-go"
"github.com/gagliardetto/solana-go/rpc"
"github.com/smartcontractkit/chainlink-ccip/chains/solana/contracts/tests/config"
"github.com/smartcontractkit/chainlink-ccip/chains/solana/contracts/tests/utils"
"github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings/external_program_cpi_stub"
"github.com/stretchr/testify/require"
)

var (
DefaultCommitment = rpc.CommitmentConfirmed
)

// deployProgram deploys a Solana program using the Solana CLI.
func deployProgram(programFile string, keypairPath string) (string, error) {

programKeyPair := "/Users/yashvardhan/chainlink-internal-integrations/solana/contracts/target/deploy/external_program_cpi_stub-keypair.json"
// Construct the CLI command: solana program deploy
cmd := exec.Command("solana", "program", "deploy", programFile, "--keypair", keypairPath, "--program-id", programKeyPair)

// Capture the command output
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr

// Run the command
if err := cmd.Run(); err != nil {
return "", fmt.Errorf("error deploying program: %s: %s", err.Error(), stderr.String())
}

// Parse and return the program ID
output := stdout.String()
return parseProgramID(output)
}

// parseProgramID parses the program ID from the deploy output.
func parseProgramID(output string) (string, error) {
// Look for the program ID in the CLI output
// Example output: "Program Id: <PROGRAM_ID>"
const prefix = "Program Id: "
startIdx := bytes.Index([]byte(output), []byte(prefix))
if startIdx == -1 {
return "", fmt.Errorf("failed to find program ID in output")
}
startIdx += len(prefix)
endIdx := bytes.Index([]byte(output[startIdx:]), []byte("\n"))
if endIdx == -1 {
endIdx = len(output)
}
return output[startIdx : startIdx+endIdx], nil
}

// TestDeployProgram is a test for deploying the Solana program.
func TestDeployProgram(t *testing.T) {
// Path to your .so file and keypair file
programFile := "/Users/yashvardhan/chainlink-internal-integrations/solana/contracts/target/deploy/external_program_cpi_stub.so"
keypairPath := "/Users/yashvardhan/.config/solana/id.json" //wallet
// keypairPath := "/Users/yashvardhan/chainlink-internal-integrations/solana/contracts/target/deploy/external_program_cpi_stub-keypair.json"

// Deploy the program
programID, err := deployProgram(programFile, keypairPath)
if err != nil {
t.Fatalf("Failed to deploy program: %v", err)
}

// // Verify the program ID (simple check for non-empty string)
if programID == "" {
t.Fatalf("Program ID is empty")
}

t.Logf("programID %s", programID)

ExternalCpiStubProgram := solana.MustPublicKeyFromBase58("EQPCTRibpsPcQNb464QVBkS1PkFfuK8kYdpd5Y17HaGh")
StubAccountPDA, _, _ := solana.FindProgramAddress([][]byte{[]byte("u8_value")}, ExternalCpiStubProgram)
t.Logf("StubAccountPDA %s", StubAccountPDA)
privateKey, _ := solana.PrivateKeyFromSolanaKeygenFile(keypairPath)
publicKey := privateKey.PublicKey()
t.Logf("publicKey from private key %s", publicKey)
solanaGoClient := rpc.New("http://127.0.0.1:8899")

external_program_cpi_stub.SetProgramID(ExternalCpiStubProgram)

ix, err := external_program_cpi_stub.NewInitializeInstruction(
StubAccountPDA,
publicKey,
solana.SystemProgramID, // 1111111
).ValidateAndBuild()

// utils.SendAndConfirm(context.Background(), t, solanaGoClient, []solana.Instruction{ix}, privateKey, config.DefaultCommitment)

// ix, _ := external_program_cpi_stub.NewEmptyInstruction().ValidateAndBuild()
require.NoError(t, err)
utils.SendAndConfirm(context.Background(), t, solanaGoClient, []solana.Instruction{ix}, privateKey, config.DefaultCommitment)

t.Logf("Program deployed successfully with ID: %s", programID)
}

// func spinUpDevNet(t *testing.T) (string, string) {
// t.Helper()
// port := "8899"
// portInt, _ := strconv.Atoi(port)

// faucetPort := "8877"
// url := "http://127.0.0.1:" + port
// wsURL := "ws://127.0.0.1:" + strconv.Itoa(portInt+1)

// args := []string{
// "--reset",
// "--rpc-port", port,
// "--faucet-port", faucetPort,
// "--ledger", t.TempDir(),
// }

// cmd := exec.Command("solana-test-validator", args...)

// var stdErr bytes.Buffer
// cmd.Stderr = &stdErr
// var stdOut bytes.Buffer
// cmd.Stdout = &stdOut
// require.NoError(t, cmd.Start())
// t.Cleanup(func() {
// assert.NoError(t, cmd.Process.Kill())
// if err2 := cmd.Wait(); assert.Error(t, err2) {
// if !assert.Contains(t, err2.Error(), "signal: killed", cmd.ProcessState.String()) {
// t.Logf("solana-test-validator\n stdout: %s\n stderr: %s", stdOut.String(), stdErr.String())
// }
// }
// })

// // Wait for api server to boot
// var ready bool
// for i := 0; i < 30; i++ {
// time.Sleep(time.Second)
// client := rpc.New(url)
// out, err := client.GetHealth(tests.Context(t))
// if err != nil || out != rpc.HealthOk {
// t.Logf("API server not ready yet (attempt %d)\n", i+1)
// continue
// }
// ready = true
// break
// }
// if !ready {
// t.Logf("Cmd output: %s\nCmd error: %s\n", stdOut.String(), stdErr.String())
// }
// require.True(t, ready)

// return url, wsURL
// }

// func getRpcClient(t *testing.T) *rpc.Client {
// url, _ := spinUpDevNet(t)
// return rpc.New(url)
// }

// func TestTokenDeploy(t *testing.T) {
// keypairPath := "/Users/yashvardhan/.config/solana/id.json" //wallet
// adminPrivateKey, _ := solana.PrivateKeyFromSolanaKeygenFile(keypairPath)
// adminPublicKey := adminPrivateKey.PublicKey()
// decimals := uint8(0)
// // amount := uint64(1000)
// solanaGoClient := rpc.New("http://127.0.0.1:8899")
// // solanaGoClient := getRpcClient(t)
// mint, _ := solana.NewRandomPrivateKey()
// mintPublicKey := mint.PublicKey()
// instructions, err := utils.CreateToken(context.Background(), config.Token2022Program, mintPublicKey, adminPublicKey, decimals, solanaGoClient, DefaultCommitment)
// utils.SendAndConfirm(context.Background(), t, solanaGoClient, instructions, adminPrivateKey, DefaultCommitment, utils.AddSigners(mint))
// require.NoError(t, err)
// }
2 changes: 1 addition & 1 deletion deployment/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ require (
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/smartcontractkit/chainlink-automation v0.8.1 // indirect
github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20241218160716-08c6052a3b40 // indirect
github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20241219100735-6badcdba9142 // indirect
github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e // indirect
github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241216163550-fa030d178ba3 // indirect
github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions deployment/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1425,6 +1425,8 @@ github.com/smartcontractkit/chainlink-ccip v0.0.0-20241217173632-814a10af5610 h1
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241217173632-814a10af5610/go.mod h1:ofnntXchdnvLT046+ZDlC8iYWoodBzhE/zo+x0/5z80=
github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20241218160716-08c6052a3b40 h1:lYKGCNxzPPn2HbA6+DLrwBjEyoPmO+FMpk7mmMXRhSc=
github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20241218160716-08c6052a3b40/go.mod h1:Bmwq4lNb5tE47sydN0TKetcLEGbgl+VxHEWp4S0LI60=
github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20241219100735-6badcdba9142 h1:iItjjn9trKLAtbvKdf96a1YDDydTC/dZV7t87kKk2m8=
github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20241219100735-6badcdba9142/go.mod h1:Bmwq4lNb5tE47sydN0TKetcLEGbgl+VxHEWp4S0LI60=
github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805 h1:Pz8jB/6qe10xT10h2S3LFYJrnebNpG5rJ/w16HZGwPQ=
github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ=
github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0=
Expand Down
41 changes: 41 additions & 0 deletions shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,44 @@ with pkgs; let
nodePackages = pkgs.nodePackages.override {inherit nodejs;};
pnpm = pnpm_9;

version = "v2.0.18";
getBinDerivation =
{
name,
filename,
sha256,
}:
pkgs.stdenv.mkDerivation rec {
inherit name;
url = "https://github.com/anza-xyz/agave/releases/download/${version}/${filename}";
src = pkgs.fetchzip {
inherit url sha256;
};

installPhase = ''
mkdir -p $out/bin
ls -lah $src
cp -r $src/bin/* $out/bin
'';
};

solanaBinaries = {
x86_64-linux = getBinDerivation {
name = "solana-cli-x86_64-linux";
filename = "solana-release-x86_64-unknown-linux-gnu.tar.bz2";
### BEGIN_LINUX_SHA256 ###
sha256 = "sha256-3FW6IMZeDtyU4GTsRIwT9BFLNzLPEuP+oiQdur7P13s=";
### END_LINUX_SHA256 ###
};
aarch64-apple-darwin = getBinDerivation {
name = "solana-cli-aarch64-apple-darwin";
filename = "solana-release-aarch64-apple-darwin.tar.bz2";
### BEGIN_DARWIN_SHA256 ###
sha256 = "sha256-6VjycYU0NU0evXoqtGAZMYGHQEKijofnFQnBJNVsb6Q=";
### END_DARWIN_SHA256 ###
};
};

mkShell' = mkShell.override {
# The current nix default sdk for macOS fails to compile go projects, so we use a newer one for now.
stdenv =
Expand Down Expand Up @@ -50,9 +88,12 @@ in
pkg-config
libudev-zero
libusb1
solanaBinaries.x86_64-linux
] ++ lib.optionals isCrib [
nur.repos.goreleaser.goreleaser-pro
patchelf
] ++ pkgs.lib.optionals (pkgs.stdenv.isDarwin && pkgs.stdenv.hostPlatform.isAarch64) [
solanaBinaries.aarch64-apple-darwin
];

shellHook = ''
Expand Down

0 comments on commit 79c2961

Please sign in to comment.