Skip to content

Commit

Permalink
feat(mesh): added WIP for mesh program
Browse files Browse the repository at this point in the history
  • Loading branch information
ogmedia committed Sep 20, 2022
1 parent 5786b35 commit a4ddaae
Show file tree
Hide file tree
Showing 10 changed files with 2,554 additions and 746 deletions.
8 changes: 8 additions & 0 deletions Anchor.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,22 @@ anchor_version = "0.25.0"
[programs.localnet]
squads_mpl = "84Ue9gKQUsStFJQCNQpsqvbceo7fKYSSCCMXxMZ5PkiW"
program_manager = "8Y5Qbdb67Ka4LcPCziyhLrGbYN2ftZ1BG11Q5PiHenLP"
mesh = "5mt41y2huXBXb8HSkMiNexABuk8GVEmrgZqEgauGtV4y"

[programs.devnet]
squads_mpl = "SMPLecH534NA9acpos4G6x7uf3LWbCAwZQE9e8ZekMu"
program_manager = "SMPLKTQhrgo22hFCVq2VGX1KAktTWjeizkhrdB1eauK"
mesh = "SMPLVC8MxZ5Bf5EfF7PaMiTCxoBAcmkbM2vkrvMK8ho"

[programs.testnet]
squads_mpl = "SMPLecH534NA9acpos4G6x7uf3LWbCAwZQE9e8ZekMu"
program_manager = "SMPLKTQhrgo22hFCVq2VGX1KAktTWjeizkhrdB1eauK"
mesh = "SMPLVC8MxZ5Bf5EfF7PaMiTCxoBAcmkbM2vkrvMK8ho"

[programs.mainnet]
squads_mpl = "SMPLecH534NA9acpos4G6x7uf3LWbCAwZQE9e8ZekMu"
program_manager = "SMPLKTQhrgo22hFCVq2VGX1KAktTWjeizkhrdB1eauK"
mesh = "SMPLVC8MxZ5Bf5EfF7PaMiTCxoBAcmkbM2vkrvMK8ho"

[registry]
url = "https://anchor.projectserum.com"
Expand Down
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

125 changes: 125 additions & 0 deletions helpers/transactions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import * as anchor from "@project-serum/anchor";
import { Connection } from "@solana/web3.js";
import { getIxPDA } from "@sqds/sdk";
import { Mesh } from "../target/types/mesh";

// some TX/IX helper functions
export const createTestTransferTransaction = async (
Expand Down Expand Up @@ -27,3 +29,126 @@ export const createBlankTransaction = async (
feePayer,
});
};

async function _executeTransaction(
transactionPDA: anchor.web3.PublicKey,
feePayer: anchor.web3.PublicKey,
program: anchor.Program<Mesh>,
): Promise<anchor.web3.TransactionInstruction> {
const transaction = await program.account.msTransaction.fetch(transactionPDA);
const ixList = await Promise.all(
[...new Array(transaction.instructionIndex)].map(async (a, i) => {
const ixIndexBN = new anchor.BN(i + 1, 10);
const [ixKey] = getIxPDA(
transactionPDA,
ixIndexBN,
program.programId
);
const ixAccount = await program.account.msInstruction.fetch(ixKey);
return { pubkey: ixKey, ixItem: ixAccount };
})
);

const ixKeysList: anchor.web3.AccountMeta[] = ixList
.map(({ pubkey, ixItem }) => {
const ixKeys: anchor.web3.AccountMeta[] =
ixItem.keys as anchor.web3.AccountMeta[];
const addSig = anchor.utils.sha256.hash("global:add_member");
const ixDiscriminator = Buffer.from(addSig, "hex");
const addData = Buffer.concat([ixDiscriminator.slice(0, 8)]);
const addAndThreshSig = anchor.utils.sha256.hash(
"global:add_member_and_change_threshold"
);
const ixAndThreshDiscriminator = Buffer.from(addAndThreshSig, "hex");
const addAndThreshData = Buffer.concat([
ixAndThreshDiscriminator.slice(0, 8),
]);
const ixData = ixItem.data as any;

const formattedKeys = ixKeys.map((ixKey, keyInd) => {
if (
(ixData.includes(addData) || ixData.includes(addAndThreshData)) &&
keyInd === 2
) {
return {
pubkey: feePayer,
isSigner: false,
isWritable: ixKey.isWritable,
};
}
return {
pubkey: ixKey.pubkey,
isSigner: false,
isWritable: ixKey.isWritable,
};
});

return [
{ pubkey, isSigner: false, isWritable: false },
{ pubkey: ixItem.programId, isSigner: false, isWritable: false },
...formattedKeys,
] as anchor.web3.AccountMeta[];
})
.reduce((p, c) => p.concat(c), []);

// [ix ix_account, ix program_id, key1, key2 ...]
const keysUnique: anchor.web3.AccountMeta[] = ixKeysList.reduce(
(prev, curr) => {
const inList = prev.findIndex(
(a) => a.pubkey.toBase58() === curr.pubkey.toBase58()
);
// if its already in the list, and has same write flag
if (inList >= 0 && prev[inList].isWritable === curr.isWritable) {
return prev;
} else {
prev.push({
pubkey: curr.pubkey,
isWritable: curr.isWritable,
isSigner: curr.isSigner,
});
return prev;
}
},
[] as anchor.web3.AccountMeta[]
);

const keyIndexMap = ixKeysList.map((a) => {
return keysUnique.findIndex(
(k) =>
k.pubkey.toBase58() === a.pubkey.toBase58() &&
k.isWritable === a.isWritable
);
});

const executeIx = await program.methods
.executeTransaction(Buffer.from(keyIndexMap))
.accounts({
multisig: transaction.ms,
transaction: transactionPDA,
member: feePayer,
})
.instruction();
executeIx.keys = executeIx.keys.concat(keysUnique);
return executeIx;
}
export async function executeTransaction(
transactionPDA: anchor.web3.PublicKey,
wallet: anchor.Wallet,
provider: anchor.Provider,
program: anchor.Program<Mesh>,
feePayer?: anchor.web3.PublicKey,
signers?: anchor.web3.Signer[],
): Promise<string> {
const payer = feePayer ?? wallet.publicKey;
const executeIx = await _executeTransaction(transactionPDA, payer, program);

const { blockhash } = await provider.connection.getLatestBlockhash();
const lastValidBlockHeight = await provider.connection.getBlockHeight();
const executeTx = new anchor.web3.Transaction({
blockhash,
lastValidBlockHeight,
feePayer: payer,
});
executeTx.add(executeIx);
return provider.sendAndConfirm(executeTx, signers);
}
25 changes: 25 additions & 0 deletions programs/mesh/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "mesh"
version = "0.0.1"
description = "Squads Mesh Program"
authors = ["Sean Lars Ganser <sean@sqds.io>"]
homepage = "https://squads.so"
repository = "https://github.com/squads-protocol/squads-mpl"
edition = "2018"
keywords = ["squads", "solana", "program", "smart-contract", "multisig"]
readme = "README.md"

[lib]
crate-type = ["cdylib", "lib"]
name = "mesh"

[features]
no-entrypoint = []
no-idl = []
no-log-ix-name = []
cpi = ["no-entrypoint"]
default = []

[dependencies]
anchor-lang = "0.25.0"
hex = "0.3.1"
2 changes: 2 additions & 0 deletions programs/mesh/Xargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[target.bpfel-unknown-unknown.dependencies.std]
features = []
20 changes: 20 additions & 0 deletions programs/mesh/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use anchor_lang::prelude::*;

#[error_code]
pub enum GraphsError {
KeyNotInMultisig,
InvalidTransactionState,
InvalidNumberOfAccounts,
InvalidInstructionAccount,
InvalidAuthorityIndex,
InvalidAuthorityType,
TransactionAlreadyExecuted,
CannotRemoveSoloMember,
InvalidThreshold,
DeprecatedTransaction,
InstructionFailed,
MaxMembersReached,
EmptyMembers,
PartialExecution,
InvalidExternalAuthority
}
Loading

0 comments on commit a4ddaae

Please sign in to comment.