# GLIP

GLIP stands for Glittr Improvement Proposals. There are # standards that are already implemented by the core team and more improvement can be proposed by anyone via GitHub.

### Core Standards

The core standards cover mostly the digital assets that can be deployed within the Glittr Ecosystem. Currently only Asset Contracts are implemented by the core team.&#x20;

1. Asset Contracts
   1. Simple Asset
      1. Free Mint
      2. Preallocated
      3. Purchase/Burn&#x20;

### Develop New GLIP

For more customized and a lot more complex logic there might be a need to develop a new GLIP. To develop a GLIP, you need to run your own localnode and write a new code that will be validate & process the new transaction based on your own specification. During development you can use the `./watch.sh` to automatically `cargo check` and `cargo test` your code.

**Prerequisites:**

[Run Localnet](/building-on-glittr/setup.md#localnet)

**Guides:**

NOTE: If you prefer to learn from example, you can look into the \`GLIP-1: Governance Contract\`  example.

To create a new GLIP standard, you need to write the new custom logic with RUST into the glittr-core's code. Most of your changes will be inside `/src/transaction`

Inside `/src/transaction/message.rs` add new enum entry to&#x20;

1. **ContractType** (if you want to add new contract)
2. **CallType** (if you want to add new call to your contract, or existing contract)

{% code title="message.rs" lineNumbers="true" %}

```rust
#[derive(Deserialize, Serialize, Clone, Debug)]
#[serde(rename_all = "snake_case")]
pub enum ContractType {
    Asset(AssetContract),
    Custom(CustomContract), // new contract
}

#[derive(Deserialize, Serialize, Clone, Debug)]
#[serde(rename_all = "snake_case")]
pub enum CallType {
    Mint(MintOption),
    Burn,
    Swap,
    // new calls only for the new conctract contract
    CreateProposal(ProposalCreation), 
    Vote(Vote),
    ExecuteProposal(BlockTxTuple),
    VetoProposal(BlockTxTuple),
}

```

{% endcode %}

Of course, you need to implement the new **ContractType** or **CallType** that you declare. Create a new file under **/src/transaction**, let's call it **custom\_contract.rs.** This is where all of your OP\_RETURN structure is being written. Since we are using rust and serialize it to JSON (for devnet), we are using `serde_json` for convenience, don't fret about the serialization. Your contract structure will be using Rust's struct, also you need to implement static `validate(&self)` here to validate your contract creation values.

{% code title="custom\_contract.rs" lineNumbers="true" %}

```rust
use super::*;

#[derive(Deserialize, Serialize, Clone, Debug)]
#[serde(rename_all = "snake_case")]
pub struct CustomContract {
    pub governance_token: BlockTxTuple,
}

...

impl CustomContract {
    pub fn validate(&self) -> Option<Flaw> {
        // Validate governance token exists
        if self.governance_token.1 == 0 {
            return Some(Flaw::InvalidBlockTxPointer);
        }
    }
}
```

{% endcode %}

If you have validation that is dependent on the runtime (block height, checking if the token really exist, etc), you must edit the `index` function inside `src/updater.rs.`

{% code title="updater.rs" lineNumbers="true" %}

```rust
            if let Some(contract_creation) = message.contract_creation {
                if let ContractType::Asset(asset_contract) = contract_creation.contract_type {
                   ... // do validation here
                    }
                }
            }
```

{% endcode %}

In the same file, you can also implement the logic for all your **CallTypes.**&#x20;

{% code title="updater.rs" lineNumbers="true" %}

```rust
            if let Some(contract_call) = message.contract_call {
                match contract_call.call_type {
                    // Implement your call types here
                    CallType::CreateProposal(_) => todo!(),
                    CallType::Vote(_) => todo!(),
                    CallType::ExecuteProposal(_) => todo!(),
                    CallType::VetoProposal(_) => todo!(),
                }
```

{% endcode %}

Make sure you add tests and the previous tests still work as well.

***

### Typescript Library

For every change in the Glittr Core code, we should update the SDK to match the new message format. Example: <https://github.com/Glittrfi/glittr-sdk-public/pull/1>

1. **ContractType** (If you want to add a new `ContractType` message, you should create a new file in `/packages/sdk/src/transaction/contract/<new_contract_creation>.ts`) .e.g&#x20;

{% code title="custom.ts" fullWidth="false" %}

```typescript
import { BlockTxTuple, PubKey } from "../../utils";

export type CustomContract = {
  custom_token: BlockTxTuple;
  custom_owner: Pubkey;
  // add more here
};
```

{% endcode %}

2. **CallType** (to add new CallType, you should create new file in `/packages/sdk/src/transaction/callType/<new_call_type>.ts`)

{% code title="custom.ts" %}

```typescript
import { BlockTxTuple } from "../../utils";

export type CustomCall = {
  title: string;
  description: string;
};

export type CustomVote = {
  proposal_id: BlockTxTuple;
};
```

{% endcode %}

After creating a new file in `/packages/sdk/src/transaction/contract/` (for new contract creation) and in `/packages/sdk/src/transaction/callType/`(for new calltype), we should add new type definition for contract creation in `packages/sdk/src/transaction/contract/types.ts`

{% code title="types.ts" %}

```typescript
import { AssetContract } from "./asset";
import { CustomContract } from "./custom";

export type ContractType = {
  asset?: AssetContract;
  custom?: CustomContract // new contract
};
```

{% endcode %}

And also add new type definition for call type in `packages/sdk/src/transaction/calltype/types.ts`&#x20;

{% code title="types.ts" %}

```typescript
import { CustomCall, CustomVote } from "./governance";

...

export type CallType =
  | { mint: MintOption }
  | { burn: {} }
  | { swap: {} }
  | { custom_call: CustomCall } // new call type
  | { custom_vote: CustomVote }; // new call type
```

{% endcode %}

After completing those steps, we can add a new function and message definition for `txBuilder`. Edit the file in `packages/sdk/src/transaction/message.ts`&#x20;

{% code title="message.ts" %}

```typescript
import { CustomContract } from "./contract/custom"; // add new import line

...

// add new message format and necessary function params for txBuilder 
export type CustomContractInstantiateFormat = {
  contract_creation: {
    contract_type: {
      custom: CustomContract
    }
  } 
}
export type CustomContractParams = {
  custom: CustomContract
}

export type TransactionFormat =
  | MintContractCallFormat
  | TransferFormat
  | PreallocatedContractFormat
  | PurchaseBurnContractFormat
  | FreeMintContractInstantiateFormat
  | CustomContractInstantiateFormat; // new transaction format
```

{% endcode %}

Now create the function for the `txBuilder` in `packages/sdk/src/transaction/index.ts`&#x20;

{% code title="index.ts" %}

```typescript
// Some code
import { CustomContractInstantiateFormat, CustomContractParams } from "./message"

...

// new function here
static customContractInstantiate(
  params: CustomContractParams
): CustomContractInstantiateFormat {
  return {
    contract_creation: {
      contract_type: {
        custom: params.custom,
      },
    },
  };
}
  
...
  
```

{% endcode %}

***

**PR Format**

Please make a PR to **<https://github.com/Glittrfi/glittr-core-public>.**

```
# Overview
This PR introduces ...

# Key Features
- Build an awesome contract
...

# Technical Changes 
- Add awesome contract structure
...

# Testing
- Add unit tests for contract validation

# Documentation
- Add inline documentation for functions
- Update README with governance features
- Add examples for creating and interacting with the awesome contract

# Future Improvements
- Add support for ...
- Implement timelock functionality for sensitive actions
- Add ...
- Consider implementing ...

# Breaking Changes
None. This is an additive change that maintains compatibility with existing contracts.

# Security Considerations
- Validated all pubkeys ...
- Implemented checks for ...
- Added safeguards against invalid configurations
- Ensured proper validation of execution permissions

# Related Issues
Closes #XXX (Add issue number if applicable)
```

**Example**

We have prepared a GLIP example, in this example we are creating a Governance Contract\* : <https://github.com/Glittrfi/glittr-core-public/pull/1>\
\
\* this example is not complete, but you should provide a finished implementation with tests


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.glittr.fi/glip.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
