Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/for devs docs #62

Merged
merged 20 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
"@rainbow-me/rainbowkit": "^1.3.3",
"@types/styled-components": "^5.1.34",
"lucide-react": "^0.314.0",
"nextra": "^2.13.4",
"nextra-theme-docs": "^2.13.4",
"sharp": "^0.33.4",
"next": "^14.2.3",
"next-compose-plugins": "^2.2.1",
"nextra": "^2.13.2",
"nextra-theme-docs": "^2.13.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"sharp": "^0.33.2",
"styled-components": "^6.1.11",
"tailwind-merge": "^2.2.1",
"viem": "^1.21.4",
Expand Down
40 changes: 20 additions & 20 deletions pages/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,35 @@
"title": "General"
},
"index": "Introduction",
"overview": "Overview",
"submit-feedback": "Submit Feedback",
"general-overview": "Overview",
"general-staking": "Staking",
"general-governance": "Governance",
"general-submit-feedback": "Submit Feedback",
"general-brand-kit": "Brand Kit",
"-- For Users": {
"title": "For Users",
"type": "separator"
},
"user-quickstart": "Quickstart",
"user-guides": "User Guides",
"user-FAQ": "FAQ",
"ecosystem-apps": "Ecosystem Apps",
"-- For Devs": {
"user-ecosystem-apps": "Ecosystem Apps",
"-- For Developers": {
"type": "separator",
"title": "For Devs"
"title": "For Developers"
},
"getting-started": "Getting Started",
"quickstart": "Quickstart",
"tools-and-resources": "Tools & Resources",
"-- Infrastructure Operators": {
"type": "separator",
"title": "Infrastructure"
},
"node-operators": "Node Operators",
"oracles": "Oracles",
"-- Advanced": {
"type": "separator",
"title": "Advanced"
},
"token-standards": "Token Standards",
"interoperability": "EVM <> Wasm Interoperability",
"dev-intro": "Introduction",
"dev-chains": "Chains",
"dev-token-standards": "Token Standards",
"dev-gas": "Gas",
"dev-smart-contracts": "Smart Contracts",
"dev-frontend-dapps": "Frontend dApps",
"dev-ecosystem-providers": "Ecosystem & Providers",
"dev-tutorials": "Tutorials",
"dev-node": "Nodes",
"dev-validators": "Validators",
"dev-advanced-concepts": "Advanced Concepts",
"dev-resources": "Resources",
"landing": {
"title": "Back to Sei ↗",
"type": "page",
Expand Down
12 changes: 12 additions & 0 deletions pages/dev-advanced-concepts/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"fee-grants": "Fee Grants",
"account-structure": "Account Structure",
"hardware-wallets": "Hardware Wallets",
"querying-historical-state": "Querying Historical State",
"oracles": "Oracles",
"execute-multiple": "Execute Multiple Transactions",
"hd-path-coin-types": "HD Path & Coin Types",
"proposals": "Proposals",
"evm-rpc-endpoints": "EVM RPC Endpoints",
"interoperability": "Interoperability"
}
27 changes: 27 additions & 0 deletions pages/dev-advanced-concepts/account-structure.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Account Structure

Both EVM derived (0x) and Sei bech32 derived addresses on Sei are derived from the same public key. Accounts are automatically linked once a transaction is broadcasted and the chain has their public key. This ensures that balances and transactions are reflected consistently across both address formats.

### How It Works

**Auto-linking**:

- When an account broadcasts a transaction, the public key is recorded on-chain. This allows for the automatic linking of EVM and Sei addresses. Balances will be reflected in both address formats once linked.

**Manual Association**:

- If the chain does not yet have the public key, users can manually associate their accounts using the `sei_associate` function. This is a gasless function that requires at least 1 wei in their account to execute. More details can be found in the [EVM RPC Endpoints documentation](https://v2.docs.sei.io/evm-rpc-endpoints#sei_associate).

### Key Points

- **Different Accounts Before Linking**: Until these accounts are linked, the chain treats the Sei address and EVM address as different accounts with different balances. This means that certain dApps may not be able to access your full balance until the accounts are linked.
- **Public Key Requirement**: The linking won’t happen until the chain has the public key. Using `sei_associate`, users can provide their public key to the chain without any gas fees, as long as they have at least 1 wei in their account.

### Example

1. **Broadcast a Transaction**: When you make any transaction from your EVM account, the public key is recorded, and the accounts get linked automatically.
2. **Manual Association Using `sei_associate`**: If the accounts are not linked automatically, you can manually associate them with the following command as long as the account you are trying to associate has at least 1 wei in it:

```
seid tx evm associate-address [optional priv key hex] --rpc=<url> --from=<sender> [flags]
```
161 changes: 161 additions & 0 deletions pages/dev-advanced-concepts/execute-multiple.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
On the Sei blockchain, you can execute multiple messages in a single transaction, which allows for more complex operations to be performed atomically. This section explains how the transaction structure works and how to add multiple messages, even of different types, in one transaction using both CosmJS and seid.

## **Transaction Structure**

A transaction on the Sei blockchain consists of the following main components:

• **Body**: Contains the list of messages to be executed, memo, timeout height, and extension options.

• **Auth Info**: Includes signer information and fee details.

• **Signatures**: Holds the signatures of the signers authorizing the transaction.

Here’s a general structure of a transaction:

```tsx
{
"body": {
"messages": [
// List of messages
],
"memo": "",
"timeout_height": "0",
"extension_options": [],
"non_critical_extension_options": []
},
"auth_info": {
"signer_infos": [],
"fee": {
"amount": [
{
"denom": "usei",
"amount": "100000"
}
],
"gas_limit": "200000",
"payer": "",
"granter": ""
}
},
"signatures": []
}
```

## **Adding Multiple Messages**

You can add multiple messages of different types in the messages array. Here’s how you can do this using CosmJS and seid.

### **Using CosmJS**

```tsx
const { DirectSecp256k1HdWallet } = require("@cosmjs/proto-signing");
const { SigningStargateClient, assertIsBroadcastTxSuccess, coins } = require("@cosmjs/stargate");

async function sendTransaction() {
const rpcEndpoint = "https://rpc-endpoint";
const mnemonic = "your mnemonic";
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: "sei" });
const [account] = await wallet.getAccounts();

const client = await SigningStargateClient.connectWithSigner(rpcEndpoint, wallet);

const msgSend = {
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
value: {
fromAddress: account.address,
toAddress: "sei1destinationaddress",
amount: coins(1000, "usei"),
},
};

const msgDelegate = {
typeUrl: "/cosmos.staking.v1beta1.MsgDelegate",
value: {
delegatorAddress: account.address,
validatorAddress: "sei1validatoraddress",
amount: coins(500, "usei"),
},
};

const fee = {
amount: coins(2000, "usei"),
gas: "200000",
};

const memo = "Transaction with multiple messages";

const result = await client.signAndBroadcast(account.address, [msgSend, msgDelegate], fee, memo);
assertIsBroadcastTxSuccess(result);
console.log(result);
}

sendTransaction().catch(console.error);
```

## Using seid

To create and broadcast a transaction with multiple messages using seid, follow these steps:

1. **Define the Unsigned Transaction**:

Create an unsigned-tx.json file with multiple messages:

```tsx
{
"body": {
"messages": [
{
"@type": "/cosmos.bank.v1beta1.MsgSend",
"from_address": "sei1sourceaddress",
"to_address": "sei1destinationaddress",
"amount": [
{
"denom": "usei",
"amount": "1000"
}
]
},
{
"@type": "/cosmos.staking.v1beta1.MsgDelegate",
"delegator_address": "sei1sourceaddress",
"validator_address": "sei1validatoraddress",
"amount": {
"denom": "usei",
"amount": "500"
}
}
],
"memo": "Transaction with multiple messages",
"timeout_height": "0",
"extension_options": [],
"non_critical_extension_options": []
},
"auth_info": {
"signer_infos": [],
"fee": {
"amount": [
{
"denom": "usei",
"amount": "2000"
}
],
"gas_limit": "200000",
"payer": "",
"granter": ""
}
},
"signatures": []
}
```

2. **Sign the Transaction**:

```tsx
seid tx sign unsigned-tx.json --from <your_account> --output-document=signed-tx.json --node <YOUR_RPC_URL>
```

3. **Broadcast the Signed Transaction**:

```tsx
seid tx broadcast signed-tx.json --node <YOUR_RPC_URL>
```
101 changes: 101 additions & 0 deletions pages/dev-advanced-concepts/fee-grants.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Fee Grants

Fee grants allow an account to pay for the transaction fees of another account, which is especially useful for onboarding new users who might not have enough tokens to cover transaction fees. This feature is supported in the Cosmos SDK.

- **How They Work**: Fee grants can be set up so that one account (the granter) can pay for the transaction fees of another account (the grantee). The granter specifies conditions under which the fees will be paid.
- **Documentation**: Detailed documentation on fee grants can be found in the [Cosmos SDK Fee Grants Documentation](https://docs.cosmos.network/v0.46/modules/feegrant/).

### Granting

seid

`seid tx feegrant grant [granter_key_or_address] [grantee]`

cosmjs

```jsx
const { SigningStargateClient, GasPrice } = require("@cosmjs/stargate");
const { DirectSecp256k1HdWallet } = require("@cosmjs/proto-signing");

async function grantFeeGrant(rpcEndpoint, granterMnemonic, granteeAddress) {
const granterWallet = await DirectSecp256k1HdWallet.fromMnemonic(granterMnemonic, { prefix: "sei" });
const [granterAccount] = await granterWallet.getAccounts();

const client = await SigningStargateClient.connectWithSigner(rpcEndpoint, granterWallet, {
gasPrice: GasPrice.fromString("0.025usei"),
});

const msg = {
typeUrl: "/cosmos.feegrant.v1beta1.MsgGrantAllowance",
value: {
granter: granterAccount.address,
grantee: granteeAddress,
allowance: {
typeUrl: "/cosmos.feegrant.v1beta1.BasicAllowance",
value: {
spendLimit: [{ denom: "usei", amount: "1000000" }],
expiration: null,
},
},
},
};

const fee = {
amount: [{ denom: "usei", amount: "5000" }],
gas: "200000",
};

const result = await client.signAndBroadcast(granterAccount.address, [msg], fee);
console.log(result);
}

const rpcEndpoint = "https://rpc-endpoint";
const granterMnemonic = "your-granter-mnemonic";
const granteeAddress = "sei1granteeaddress";

grantFeeGrant(rpcEndpoint, granterMnemonic, granteeAddress);
```

### Revoking

seid

`seid tx feegrant revoke [granter] [grantee] [flags]`

cosmjs

```jsx
const { SigningStargateClient, GasPrice } = require("@cosmjs/stargate");
const { DirectSecp256k1HdWallet } = require("@cosmjs/proto-signing");

async function revokeFeeGrant(rpcEndpoint, granterMnemonic, granteeAddress) {
const granterWallet = await DirectSecp256k1HdWallet.fromMnemonic(granterMnemonic, { prefix: "sei" });
const [granterAccount] = await granterWallet.getAccounts();

const client = await SigningStargateClient.connectWithSigner(rpcEndpoint, granterWallet, {
gasPrice: GasPrice.fromString("0.025usei"),
});

const msg = {
typeUrl: "/cosmos.feegrant.v1beta1.MsgRevokeAllowance",
value: {
granter: granterAccount.address,
grantee: granteeAddress,
},
};

const fee = {
amount: [{ denom: "usei", amount: "5000" }],
gas: "200000",
};

const result = await client.signAndBroadcast(granterAccount.address, [msg], fee);
console.log(result);
}

const rpcEndpoint = "https://rpc-endpoint";
const granterMnemonic = "your-granter-mnemonic";
const granteeAddress = "sei1granteeaddress";

revokeFeeGrant(rpcEndpoint, granterMnemonic, granteeAddress);
```
Loading
Loading