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.
Asset Contracts
Simple Asset
Free Mint
Preallocated
Purchase/Burn
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:
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
ContractType (if you want to add new contract)
CallType (if you want to add new call to your contract, or existing contract)
#[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),
}
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.
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);
}
}
}
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.
if let Some(contract_creation) = message.contract_creation {
if let ContractType::Asset(asset_contract) = contract_creation.contract_type {
... // do validation here
}
}
}
In the same file, you can also implement the logic for all your CallTypes.
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!(),
}
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
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
import { BlockTxTuple, PubKey } from "../../utils";
export type CustomContract = {
custom_token: BlockTxTuple;
custom_owner: Pubkey;
// add more here
};
CallType (to add new CallType, you should create new file in
/packages/sdk/src/transaction/callType/<new_call_type>.ts
)
import { BlockTxTuple } from "../../utils";
export type CustomCall = {
title: string;
description: string;
};
export type CustomVote = {
proposal_id: BlockTxTuple;
};
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
import { AssetContract } from "./asset";
import { CustomContract } from "./custom";
export type ContractType = {
asset?: AssetContract;
custom?: CustomContract // new contract
};
And also add new type definition for call type in packages/sdk/src/transaction/calltype/types.ts
import { CustomCall, CustomVote } from "./governance";
...
export type CallType =
| { mint: MintOption }
| { burn: {} }
| { swap: {} }
| { custom_call: CustomCall } // new call type
| { custom_vote: CustomVote }; // new call type
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
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
Now create the function for the txBuilder
in packages/sdk/src/transaction/index.ts
// Some code
import { CustomContractInstantiateFormat, CustomContractParams } from "./message"
...
// new function here
static customContractInstantiate(
params: CustomContractParams
): CustomContractInstantiateFormat {
return {
contract_creation: {
contract_type: {
custom: params.custom,
},
},
};
}
...
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
Last updated