added dev files

This commit is contained in:
spacemandev 2022-05-24 16:27:04 +02:00
parent ebd2a14cb6
commit 354d6c5fee
33 changed files with 4091 additions and 12 deletions

7
anchor-contributor/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
.anchor
.DS_Store
target
**/*.rs.bk
node_modules
test-ledger

View File

@ -0,0 +1,8 @@
.anchor
.DS_Store
target
node_modules
dist
build
test-ledger

View File

@ -0,0 +1,14 @@
[features]
seeds = false
[programs.localnet]
anchor_contributor = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"
[registry]
url = "https://anchor.projectserum.com"
[provider]
cluster = "localnet"
wallet = "./tests/test_keypair.json"
[scripts]
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"

1318
anchor-contributor/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
[workspace]
members = [
"programs/*"
]

View File

@ -0,0 +1,12 @@
// 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("@project-serum/anchor");
module.exports = async function (provider) {
// Configure client to use the provider.
anchor.setProvider(provider);
// Add your deploy script here.
};

View File

@ -0,0 +1,21 @@
{
"scripts": {
"lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w",
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
},
"dependencies": {
"@certusone/wormhole-sdk": "^0.3.4",
"@project-serum/anchor": "^0.24.2",
"ethers": "^5.6.7"
},
"devDependencies": {
"@types/bn.js": "^5.1.0",
"@types/chai": "^4.3.0",
"@types/mocha": "^9.0.0",
"chai": "^4.3.4",
"mocha": "^9.0.3",
"prettier": "^2.6.2",
"ts-mocha": "^8.0.0",
"typescript": "^4.3.5"
}
}

View File

@ -0,0 +1,25 @@
[package]
name = "anchor-contributor"
version = "0.1.0"
description = "ICCO Contributor"
edition = "2021"
[lib]
crate-type = ["cdylib", "lib"]
name = "anchor_contributor"
[features]
no-entrypoint = []
no-idl = []
no-log-ix-name = []
cpi = ["no-entrypoint"]
default = []
[profile.release]
overflow-checks = true
[dependencies]
anchor-lang = "0.24.2"
num-traits = "0.2"
num-derive = "0.3"
borsh = "0.9.3"

View File

@ -0,0 +1,3 @@
pub const CORE_BRIDGE_ADDRESS: &str = "Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o";
pub const TOKEN_BRIDGE_ADDRESS: &str = "B6RHG3mfcckmrYN1UhmJzyS1XX3fZKbkeUcpJe9Sy3FE";
pub const SEED_PREFIX_SALE: &str = "icco-sale";

View File

@ -0,0 +1,55 @@
use anchor_lang::prelude::*;
use crate::state::*;
use crate::constants::*;
use std::str::FromStr;
use crate::wormhole::*;
#[derive(Accounts)]
#[instruction(conductor_chain:u16, conductor_address:Vec<u8>)]
pub struct CreateContributor<'info> {
#[account(
init,
payer = owner,
space = 8 + Contributor::MAXIMUM_SIZE,
seeds = [
b"contributor".as_ref(),
conductor_address.as_ref()
],
bump
)]
pub contributor: Account<'info, Contributor>,
#[account(mut)]
pub owner: Signer<'info>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
pub struct InitSale<'info> {
pub contributor: Account<'info, Contributor>,
#[account(
init,
seeds = [
SEED_PREFIX_SALE.as_bytes().as_ref(),
(PostedMessageData::try_from_slice(&core_bridge_vaa.data.borrow())?.0).sequence.to_be_bytes().as_ref()
],
payer = owner,
bump,
space = Sale::MAXIMUM_SIZE
)]
pub sale: Account<'info, Sale>,
#[account(
constraint = core_bridge_vaa.to_account_info().owner == &Pubkey::from_str(CORE_BRIDGE_ADDRESS).unwrap(),
constraint = (PostedMessageData::try_from_slice(&core_bridge_vaa.data.borrow())?.0).emitter_chain == contributor.conductor_chain,
constraint = (PostedMessageData::try_from_slice(&core_bridge_vaa.data.borrow())?.0).emitter_address == contributor.conductor_address
)]
/// CHECK: This account is owned by Core Bridge so we trust it
pub core_bridge_vaa: AccountInfo<'info>,
#[account(mut)]
pub owner: Signer<'info>,
pub system_program: Program<'info, System>,
}

View File

@ -0,0 +1,25 @@
use anchor_lang::prelude::*;
#[error_code]
pub enum ContributorError {
#[msg("InvalidConductor")]
InvalidConductor,
}
#[error_code]
pub enum SaleError {
#[msg("IncorrectSale")]
IncorrectSale,
#[msg("IncorrectVaaPayload")]
IncorrectVaaPayload,
#[msg("InvalidVaaAction")]
InvalidVaaAction,
#[msg("SaleEnded")]
SaleEnded,
#[msg("SaleNotFinished")]
SaleNotFinished,
}

View File

@ -0,0 +1,45 @@
use anchor_lang::prelude::*;
mod context;
mod state;
mod wormhole;
mod error;
mod constants;
use constants::*;
use context::*;
use state::*;
use error::*;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod anchor_contributor {
use super::*;
pub fn create_contributor(
ctx: Context<CreateContributor>,
conductor_chain: u16,
conductor_address: Vec<u8>,
) -> Result<()> {
let contributor = &mut ctx.accounts.contributor;
// there isn't a solana conductor (yet? bwahaha)
require!(conductor_chain != 1u16, ContributorError::InvalidConductor);
contributor.conductor_chain = conductor_chain;
contributor.conductor_address =
conductor_address.try_into().expect("incorrect byte length");
contributor.owner = ctx.accounts.owner.key();
Ok(())
}
pub fn init_sale(ctx:Context<InitSale>) -> Result<()> {
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize {}

View File

@ -0,0 +1,60 @@
use anchor_lang::prelude::*;
use crate::wormhole::*;
use num_derive::*;
use borsh::{BorshDeserialize};
use std::{
io::Write,
};
#[account]
#[derive(Default)]
pub struct Contributor {
pub owner: Pubkey,
pub conductor_chain: u16,
pub conductor_address: [u8; 32],
}
impl Contributor {
pub const MAXIMUM_SIZE: usize = 2 + 32 + 32 + 1;
}
#[account]
pub struct Sale {
token_address: Vec<u8>, // 32
token_chain: u16, // 2
token_decimals: u8, // 1
times: SaleTimes, // 8 + 8
recipient: [u8; 32], // 32
num_accepted: u8, // 1
status: SaleStatus, // 1
pub id: Vec<u8>, // 32
pub bump: u8, // 1
}
impl Sale {
pub const MAXIMUM_SIZE: usize = 32 + 32 + 2 + 1 + 8 + 8 + 32 + 1 + 1 + 1;
}
pub fn parse_sale_payload(payload: Vec<u8>){
}
#[derive(AnchorSerialize, AnchorDeserialize, Copy, Clone, PartialEq, Eq)]
pub struct SaleTimes {
start: u64,
end: u64,
}
#[derive(
AnchorSerialize, AnchorDeserialize, FromPrimitive, ToPrimitive, Copy, Clone, PartialEq, Eq,
)]
pub enum SaleStatus {
Active,
Sealed,
Aborted,
}

View File

@ -0,0 +1,111 @@
use anchor_lang::prelude::*;
use borsh::{BorshDeserialize, BorshSerialize};
use std::{
io::Write,
};
#[derive(AnchorDeserialize, AnchorSerialize)]
pub struct PostMessageData {
/// Unique nonce for this message
pub nonce: u32,
/// Message payload
pub payload: Vec<u8>,
/// Commitment Level required for an attestation to be produced
pub consistency_level: ConsistencyLevel,
}
#[derive(AnchorDeserialize, AnchorSerialize)]
pub enum ConsistencyLevel {
Confirmed,
Finalized
}
#[derive(AnchorDeserialize, AnchorSerialize)]
pub enum Instruction{
Initialize,
PostMessage,
PostVAA,
SetFees,
TransferFees,
UpgradeContract,
UpgradeGuardianSet,
VerifySignatures,
}
#[derive(AnchorDeserialize, AnchorSerialize, Clone)]
pub struct BridgeData {
/// The current guardian set index, used to decide which signature sets to accept.
pub guardian_set_index: u32,
/// Lamports in the collection account
pub last_lamports: u64,
/// Bridge configuration, which is set once upon initialization.
pub config: BridgeConfig,
}
#[derive(AnchorDeserialize, AnchorSerialize, Clone)]
pub struct BridgeConfig {
/// Period for how long a guardian set is valid after it has been replaced by a new one. This
/// guarantees that VAAs issued by that set can still be submitted for a certain period. In
/// this period we still trust the old guardian set.
pub guardian_set_expiration_time: u32,
/// Amount of lamports that needs to be paid to the protocol to post a message
pub fee: u64,
}
#[derive(Debug)]
#[repr(transparent)]
pub struct PostedMessageData(pub MessageData);
#[derive(Debug, Default, BorshDeserialize, BorshSerialize)]
pub struct MessageData {
/// Header of the posted VAA
pub vaa_version: u8,
/// Level of consistency requested by the emitter
pub consistency_level: u8,
/// Time the vaa was submitted
pub vaa_time: u32,
/// Account where signatures are stored
pub vaa_signature_account: Pubkey,
/// Time the posted message was created
pub submission_time: u32,
/// Unique nonce for this message
pub nonce: u32,
/// Sequence number of this message
pub sequence: u64,
/// Emitter of the message
pub emitter_chain: u16,
/// Emitter of the message
pub emitter_address: [u8; 32],
/// Message payload
pub payload: Vec<u8>,
}
impl AnchorSerialize for PostedMessageData {
fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
writer.write(b"msg")?;
BorshSerialize::serialize(&self.0, writer)
}
}
impl AnchorDeserialize for PostedMessageData {
fn deserialize(buf: &mut &[u8]) -> std::io::Result<Self> {
*buf = &buf[3..];
Ok(PostedMessageData(
<MessageData as BorshDeserialize>::deserialize(buf)?,
))
}
}

View File

@ -0,0 +1,43 @@
import * as anchor from "@project-serum/anchor";
import { Program } from "@project-serum/anchor";
import { AnchorContributor } from "../target/types/anchor_contributor";
import {
tryNativeToUint8Array
} from '@certusone/wormhole-sdk';
import { findProgramAddressSync } from "@project-serum/anchor/dist/cjs/utils/pubkey";
import fs from 'fs';
describe("anchor-contributor", () => {
// Configure the client to use the local cluster.
anchor.setProvider(anchor.AnchorProvider.env());
const program = anchor.workspace.AnchorContributor as Program<AnchorContributor>;
const CONDUCTOR_CHAIN = 2;
const CONDUCTOR_ADDRESS = tryNativeToUint8Array('0x5c49f34D92316A2ac68d10A1e2168e16610e84f9', "ethereum");
const owner = anchor.web3.Keypair.fromSecretKey(Uint8Array.from(JSON.parse(fs.readFileSync("./tests/test_keypair.json").toString())))
const [contributor_acc, contributor_bmp] = findProgramAddressSync([
Buffer.from("contributor"),
CONDUCTOR_ADDRESS
], program.programId)
it("creates conductor", async () => {
await program.methods
.createContributor(
CONDUCTOR_CHAIN,
Buffer.from(CONDUCTOR_ADDRESS)
)
.accounts({
owner: owner.publicKey,
contributor: contributor_acc,
systemProgram: anchor.web3.SystemProgram.programId
})
.rpc()
console.log(await program.account.contributor.fetch(contributor_acc));
});
it("initalizes a sale", async () => {
})
});

View File

@ -0,0 +1 @@
[128,234,237,75,126,9,5,95,22,89,161,204,162,155,126,118,233,0,87,171,69,102,211,233,50,152,163,63,145,5,132,63,158,238,105,62,204,112,139,148,240,143,108,17,236,215,6,163,114,46,101,158,161,227,52,43,109,225,184,233,161,235,186,224]

View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"types": ["mocha", "chai"],
"typeRoots": ["./node_modules/@types"],
"lib": ["es2015"],
"module": "commonjs",
"target": "es6",
"esModuleInterop": true
}
}

2256
anchor-contributor/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,15 @@
[features]
seeds = false
[programs.localnet]
icco = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"
icco_contributor = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"
contributor = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"
[registry]
url = "https://anchor.projectserum.com"
[provider]
cluster = "localnet"
wallet = "/Users/spacemandev/.config/solana/id.json"
wallet = "~/.config/solana/id.json"
[scripts]
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"

View File

@ -421,6 +421,13 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "contributor"
version = "0.1.0"
dependencies = [
"anchor-lang",
]
[[package]]
name = "cpufeatures"
version = "0.2.2"
@ -604,7 +611,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "icco-contributor"
name = "icco_contributor"
version = "0.1.0"
dependencies = [
"anchor-lang",

View File

@ -0,0 +1,22 @@
[package]
name = "contributor"
version = "0.1.0"
description = "Created with Anchor"
edition = "2021"
[lib]
crate-type = ["cdylib", "lib"]
name = "contributor"
[features]
no-entrypoint = []
no-idl = []
no-log-ix-name = []
cpi = ["no-entrypoint"]
default = []
[profile.release]
overflow-checks = true
[dependencies]
anchor-lang = "0.24.2"

View File

@ -0,0 +1,2 @@
[target.bpfel-unknown-unknown.dependencies.std]
features = []

View File

@ -0,0 +1,15 @@
use anchor_lang::prelude::*;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod contributor {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize {}

View File

@ -1,5 +1,5 @@
[package]
name = "icco-contributor"
name = "icco_contributor"
version = "0.1.0"
description = "ICCO Contributor"
edition = "2021"

View File

@ -0,0 +1,2 @@
[target.bpfel-unknown-unknown.dependencies.std]
features = []

View File

@ -13,6 +13,10 @@ pub mod wormhole;
pub mod icco_contributor {
use super::*;
pub fn debug(ctx: Context<Debug>) -> Result<()> {
Ok(())
}
pub fn create_contributor(
ctx: Context<CreateContributor>,
conductor_chain: u16,
@ -30,6 +34,7 @@ pub mod icco_contributor {
conductor_address.try_into().expect("incorrect byte length");
contributor.wormhole = wormhole;
contributor.token_bridge = token_bridge;
contributor.owner = ctx.accounts.owner.key();
Ok(())
}
@ -46,3 +51,8 @@ pub mod icco_contributor {
instructions::sale_aborted(ctx)
}
}
#[derive(Accounts)]
pub struct Debug{
}

View File

@ -8,6 +8,7 @@ pub enum ContributorError {
#[account]
pub struct Contributor {
pub owner: Pubkey,
pub conductor_chain: u16,
pub conductor_address: [u8; 32],
pub wormhole: Pubkey, // 32 bytes

View File

@ -1,16 +1,17 @@
import * as anchor from "@project-serum/anchor";
import { Program } from "@project-serum/anchor";
import { Icco } from "../target/types/icco";
import { Contributor } from "../target/types/contributor";
describe("icco", () => {
// Configure the client to use the local cluster.
anchor.setProvider(anchor.AnchorProvider.env());
const program = anchor.workspace.Icco as Program<Icco>;
it("Is initialized!", async () => {
// Add your test here.
const tx = await program.methods.initialize().rpc();
console.log("Your transaction signature", tx);
const program = anchor.workspace.contributor as Program<Contributor>;
console.log(program.programId);
it("creates a contributor", async () => {
await program.methods.initialize().accounts({}).rpc();
});
});
});