Skip to content

Commit 40aadd6

Browse files
authored
feat(lazer): add utils for adding and checking ed25519 signers to solana contract (#2788)
* feat(lazer): add utils for adding and checking ed25519 signers to solana contract * refactor(lazer): move ed25519 instruction code to solana contract package * chore: fix unrelated formatting * chore: fix constant usage * chore: fix ci * chore: fix CI 2 * fix CI
1 parent c673261 commit 40aadd6

File tree

14 files changed

+622
-519
lines changed

14 files changed

+622
-519
lines changed

doc/code-guidelines.md

Lines changed: 173 additions & 173 deletions
Large diffs are not rendered by default.

doc/rust-code-guidelines.md

Lines changed: 284 additions & 286 deletions
Large diffs are not rendered by default.

governance/xc_admin/packages/xc_admin_cli/src/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ import {
5757
} from "@pythnetwork/pyth-solana-receiver";
5858
import {
5959
SOLANA_LAZER_PROGRAM_ID,
60-
SOLANA_STORAGE_ID,
60+
SOLANA_LAZER_STORAGE_ID,
6161
} from "@pythnetwork/pyth-lazer-sdk";
6262

6363
import { LedgerNodeWallet } from "./ledger";
@@ -978,7 +978,7 @@ multisigCommand(
978978
.update(trustedSigner, expiryTime)
979979
.accounts({
980980
topAuthority: await vault.getVaultAuthorityPDA(targetCluster),
981-
storage: SOLANA_STORAGE_ID,
981+
storage: new PublicKey(SOLANA_LAZER_STORAGE_ID),
982982
})
983983
.instruction();
984984

@@ -1010,7 +1010,7 @@ multisigCommand(
10101010
const trustedSigner = Buffer.from(options.signer, "hex");
10111011
const expiryTime = new BN(options.expiryTime);
10121012

1013-
const programId = SOLANA_LAZER_PROGRAM_ID;
1013+
const programId = new PublicKey(SOLANA_LAZER_PROGRAM_ID);
10141014
const programDataAccount = PublicKey.findProgramAddressSync(
10151015
[programId.toBuffer()],
10161016
BPF_UPGRADABLE_LOADER,
@@ -1039,7 +1039,7 @@ multisigCommand(
10391039
// Create Anchor program instance
10401040
const lazerProgram = new Program(
10411041
lazerIdl as Idl,
1042-
SOLANA_LAZER_PROGRAM_ID,
1042+
programId,
10431043
vault.getAnchorProvider(),
10441044
);
10451045

@@ -1048,7 +1048,7 @@ multisigCommand(
10481048
.updateEcdsaSigner(trustedSigner, expiryTime)
10491049
.accounts({
10501050
topAuthority: await vault.getVaultAuthorityPDA(targetCluster),
1051-
storage: SOLANA_STORAGE_ID,
1051+
storage: new PublicKey(SOLANA_LAZER_STORAGE_ID),
10521052
})
10531053
.instruction();
10541054

governance/xc_admin/packages/xc_admin_common/src/multisig_transaction/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,9 @@ export class MultisigParser {
166166
return SolanaStakingMultisigInstruction.fromTransactionInstruction(
167167
instruction,
168168
);
169-
} else if (instruction.programId.equals(SOLANA_LAZER_PROGRAM_ID)) {
169+
} else if (
170+
instruction.programId.equals(new PublicKey(SOLANA_LAZER_PROGRAM_ID))
171+
) {
170172
return LazerMultisigInstruction.fromInstruction(instruction);
171173
} else {
172174
return UnrecognizedProgram.fromTransactionInstruction(instruction);

lazer/contracts/solana/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
"check-trusted-signer": "pnpm ts-node scripts/check_trusted_signer.ts"
1111
},
1212
"dependencies": {
13-
"@coral-xyz/anchor": "^0.30.1"
13+
"@coral-xyz/anchor": "^0.30.1",
14+
"@pythnetwork/pyth-lazer-sdk": "workspace:*",
15+
"@solana/web3.js": "^1.98.0",
16+
"@solana/buffer-layout": "^4.0.1"
1417
},
1518
"devDependencies": {
1619
"@types/bn.js": "^5.1.0",

lazer/contracts/solana/programs/pyth-lazer-solana-contract/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(unexpected_cfgs)] // anchor macro triggers it
2+
13
mod signature;
24

35
use {
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import * as anchor from "@coral-xyz/anchor";
2+
import { Program } from "@coral-xyz/anchor";
3+
import { PythLazerSolanaContract } from "../target/types/pyth_lazer_solana_contract";
4+
import * as pythLazerSolanaContractIdl from "../target/idl/pyth_lazer_solana_contract.json";
5+
import yargs from "yargs/yargs";
6+
import { readFileSync } from "fs";
7+
import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
8+
9+
// Add a trusted signer or change its expiry time.
10+
//
11+
// Example:
12+
// pnpm ts-node scripts/add_ed25519_signer.ts --url 'https://api.testnet.solana.com' \
13+
// --keypair-path .../key.json --trusted-signer HaXscpSUcbCLSnPQB8Z7H6idyANxp1mZAXTbHeYpfrJJ \
14+
// --expiry-time-seconds 2057930841
15+
async function main() {
16+
let argv = await yargs(process.argv.slice(2))
17+
.options({
18+
url: { type: "string", demandOption: true },
19+
"keypair-path": { type: "string", demandOption: true },
20+
"trusted-signer": { type: "string", demandOption: true },
21+
"expiry-time-seconds": { type: "number", demandOption: true },
22+
})
23+
.parse();
24+
25+
const keypair = anchor.web3.Keypair.fromSecretKey(
26+
new Uint8Array(JSON.parse(readFileSync(argv.keypairPath, "ascii"))),
27+
);
28+
29+
const wallet = new NodeWallet(keypair);
30+
const connection = new anchor.web3.Connection(argv.url, {
31+
commitment: "confirmed",
32+
});
33+
const provider = new anchor.AnchorProvider(connection, wallet);
34+
35+
const program: Program<PythLazerSolanaContract> = new Program(
36+
pythLazerSolanaContractIdl as PythLazerSolanaContract,
37+
provider,
38+
);
39+
40+
await program.methods
41+
.update(
42+
new anchor.web3.PublicKey(argv.trustedSigner),
43+
new anchor.BN(argv.expiryTimeSeconds),
44+
)
45+
.accounts({})
46+
.rpc();
47+
console.log("signer updated");
48+
}
49+
50+
main();

lazer/contracts/solana/scripts/check_trusted_signer.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ async function main() {
4040

4141
// Print storage info
4242
console.log("Storage Account Info:");
43-
console.log("--------------------");
43+
console.log("---------------------");
4444
console.log("Top Authority:", storage.topAuthority.toBase58());
4545
console.log("Treasury:", storage.treasury.toBase58());
46-
console.log("\nTrusted Signers:");
47-
console.log("----------------");
46+
console.log("\nTrusted Ed25519 Signers:");
47+
console.log("------------------------");
4848

4949
const trustedSigners = storage.trustedSigners.slice(
5050
0,
@@ -67,7 +67,7 @@ async function main() {
6767
}
6868

6969
console.log("\nTrusted ECDSA Signers:");
70-
console.log("----------------");
70+
console.log("----------------------");
7171

7272
const trustedEcdsaSigners = storage.trustedEcdsaSigners.slice(
7373
0,
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import * as anchor from "@coral-xyz/anchor";
2+
import { Program } from "@coral-xyz/anchor";
3+
import { PythLazerSolanaContract } from "../target/types/pyth_lazer_solana_contract";
4+
import * as pythLazerSolanaContractIdl from "../target/idl/pyth_lazer_solana_contract.json";
5+
import yargs from "yargs/yargs";
6+
import { readFileSync } from "fs";
7+
import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
8+
import { createEd25519Instruction } from "../src/ed25519";
9+
import {
10+
sendAndConfirmTransaction,
11+
SendTransactionError,
12+
SYSVAR_INSTRUCTIONS_PUBKEY,
13+
Transaction,
14+
} from "@solana/web3.js";
15+
16+
async function main() {
17+
let argv = await yargs(process.argv.slice(2))
18+
.options({
19+
url: { type: "string", demandOption: true },
20+
"keypair-path": { type: "string", demandOption: true },
21+
message: { type: "string", demandOption: true },
22+
})
23+
.parse();
24+
25+
const keypair = anchor.web3.Keypair.fromSecretKey(
26+
new Uint8Array(JSON.parse(readFileSync(argv.keypairPath, "ascii"))),
27+
);
28+
29+
const wallet = new NodeWallet(keypair);
30+
const connection = new anchor.web3.Connection(argv.url, {
31+
commitment: "confirmed",
32+
});
33+
const provider = new anchor.AnchorProvider(connection, wallet);
34+
35+
const program: Program<PythLazerSolanaContract> = new Program(
36+
pythLazerSolanaContractIdl as PythLazerSolanaContract,
37+
provider,
38+
);
39+
40+
const instructionMessage = Buffer.from(argv.message, "hex");
41+
const ed25519Instruction = createEd25519Instruction(
42+
instructionMessage,
43+
1,
44+
12,
45+
);
46+
const lazerInstruction = await program.methods
47+
.verifyMessage(instructionMessage, 0, 0)
48+
.accounts({
49+
payer: wallet.publicKey,
50+
instructionsSysvar: SYSVAR_INSTRUCTIONS_PUBKEY,
51+
})
52+
.instruction();
53+
54+
const transaction = new Transaction().add(
55+
ed25519Instruction,
56+
lazerInstruction,
57+
);
58+
console.log("transaction:", transaction);
59+
60+
try {
61+
const signature = await sendAndConfirmTransaction(
62+
connection,
63+
transaction,
64+
[wallet.payer],
65+
{
66+
skipPreflight: true,
67+
},
68+
);
69+
console.log("Transaction confirmed with signature:", signature);
70+
} catch (e) {
71+
console.log("error", e);
72+
console.log(e.getLogs());
73+
}
74+
}
75+
76+
main();
File renamed without changes.

lazer/sdk/js/package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pythnetwork/pyth-lazer-sdk",
3-
"version": "1.0.0",
3+
"version": "2.0.0",
44
"description": "Pyth Lazer SDK",
55
"publishConfig": {
66
"access": "public"
@@ -59,8 +59,6 @@
5959
"license": "Apache-2.0",
6060
"dependencies": {
6161
"@isaacs/ttlcache": "^1.4.1",
62-
"@solana/buffer-layout": "^4.0.1",
63-
"@solana/web3.js": "^1.98.0",
6462
"isomorphic-ws": "^5.0.0",
6563
"ts-log": "^2.2.7",
6664
"ws": "^8.18.0"

lazer/sdk/js/src/constants.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import { PublicKey } from "@solana/web3.js";
2-
3-
export const SOLANA_LAZER_PROGRAM_ID = new PublicKey(
4-
"pytd2yyk641x7ak7mkaasSJVXh6YYZnC7wTmtgAyxPt",
5-
);
6-
export const SOLANA_STORAGE_ID = new PublicKey(
7-
"3rdJbqfnagQ4yx9HXJViD4zc4xpiSqmFsKpPuSCQVyQL",
8-
);
1+
export const SOLANA_LAZER_PROGRAM_ID =
2+
"pytd2yyk641x7ak7mkaasSJVXh6YYZnC7wTmtgAyxPt";
3+
export const SOLANA_LAZER_STORAGE_ID =
4+
"3rdJbqfnagQ4yx9HXJViD4zc4xpiSqmFsKpPuSCQVyQL";

lazer/sdk/js/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
export * from "./client.js";
22
export * from "./protocol.js";
3-
export * from "./ed25519.js";
43
export * from "./constants.js";

pnpm-lock.yaml

Lines changed: 16 additions & 37 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)