Skip to content
This repository has been archived by the owner on Jul 15, 2022. It is now read-only.

Commit

Permalink
Solana staking (#1844)
Browse files Browse the repository at this point in the history
* solana add initial staking support

* solana improve staking

* solana fix typos

* solana fix cli format for staking

* solana add device fields for stake create acc

* solana add stake delegate support

* solana fix lint

* solana add stake undelegate

* solana add stake withdraw

* solana add stake split

* solana add stakes loading

* solana improve staking

* solana introduce solana resources

* solana add preload data

* solana add hydrate to bridge

* solana add stake actions

* solana improve staking

* solana add meta to validators

* solana add validator name

* solana fix seed for stake accs

* solana add stake reward

* solana improve staking

* solana stake add withdrawable amount

* solana refactor framework

* solana fix tests

* solana make auto delegation mandatory

* solana sort stakes

* solana fix error key

* solana add delegation validator validation

* solana add staking create acc tests

* solana add staking delegate tests

* solana add stake undelegate tests

* solana remove redundant checks for stake delegation

* solana skip options validations on cli level

* solana skip undelegate options validations on cli level

* solana improve staking tests

* solana add delegatable check to staking

* solana fix estimate max spendable

* solana add delegation active test

* solana add stake state tests

* solana introduce validators app validators

* solana add validators for testnet & devnet

* solana refactor validators app validators

* solana update meta of stakes

* solana update sort order of stakes

* solana add delegated op type

* solana shuffle staking validators

* solana fix stake withdraw optimistic value

* solana clean comments

* solana update mock data

* solana add initial staking bot specs

* solana add staking bot specs

* solana move ledger vote acc to utils

* solana add swap util

* solana update device tx config

* solana fix lint

* Add bot for Solana

* Solana staking integration (#1825)

* solana add initial staking support

* solana improve staking

* solana fix typos

* solana fix cli format for staking

* solana add device fields for stake create acc

* solana add stake delegate support

* solana fix lint

* solana add stake undelegate

* solana add stake withdraw

* solana add stake split

* solana add stakes loading

* solana improve staking

* solana introduce solana resources

* solana add preload data

* solana add hydrate to bridge

* solana add stake actions

* solana improve staking

* solana add meta to validators

* solana add validator name

* solana fix seed for stake accs

* solana add stake reward

* solana improve staking

* solana stake add withdrawable amount

* solana refactor framework

* solana fix tests

* solana make auto delegation mandatory

* solana sort stakes

* solana fix error key

* solana add delegation validator validation

* solana add staking create acc tests

* solana add staking delegate tests

* solana add stake undelegate tests

* solana remove redundant checks for stake delegation

* solana skip options validations on cli level

* solana skip undelegate options validations on cli level

* solana improve staking tests

* solana add delegatable check to staking

* solana fix estimate max spendable

* solana add delegation active test

* solana add stake state tests

* solana introduce validators app validators

* solana add validators for testnet & devnet

* solana refactor validators app validators

* solana update meta of stakes

* solana update sort order of stakes

* solana add delegated op type

* solana shuffle staking validators

* solana fix stake withdraw optimistic value

* solana clean comments

* solana update mock data

* solana add initial staking bot specs

* solana add staking bot specs

* solana move ledger vote acc to utils

* solana add swap util

* solana update device tx config

* solana fix lint

* Change seed for Solana bot

* Change seed again for Solana bot

* trigger bot

* solana add stake percent calc fn

* solana update spec for new nano app

* solana set minimum required nano app version

* solana add validators app url env variable

* fix bad merge

* trigger bot

* trigger bot

* trigger bot

* trigger bot

* Solana bot - increase timeout and decrease minimum to delegate

* trigger bot

* trigger bot

* trigger bot

* trigger bot

* Setup the bot to not use the validators.app proxy (yet)

* Replace all deprecated uses of open(deviceId) with withDevice

* Solana - replace open(deviceId) with withDevice

* Remove custom data

* Update solana bot

Co-authored-by: konoart <[email protected]>
Co-authored-by: konoart <[email protected]>
Co-authored-by: lambertkevin <[email protected]>
  • Loading branch information
4 people committed Apr 11, 2022
1 parent fcc3077 commit a63d453
Show file tree
Hide file tree
Showing 42 changed files with 4,201 additions and 1,384 deletions.
79 changes: 79 additions & 0 deletions .github/workflows/bot-solana-silicium.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Bot 'Solana on Silicium'
on:
push:
branches:
- family/solana

jobs:
start-runner:
name: "start ec2 instance (Linux)"
if: ${{ always() }}
uses: ledgerhq/actions/.github/workflows/start-linux-runner.yml@main
secrets:
CI_BOT_TOKEN: ${{ secrets.CI_BOT_TOKEN }}

stop-runner:
name: "stop ec2 instance (Linux)"
needs: [start-runner, run-bot]
uses: ledgerhq/actions/.github/workflows/stop-linux-runner.yml@main
if: ${{ always() }}
with:
label: ${{ needs.start-runner.outputs.label }}
ec2-instance-id: ${{ needs.start-runner.outputs.ec2-instance-id }}
secrets:
CI_BOT_TOKEN: ${{ secrets.CI_BOT_TOKEN }}

run-bot:
needs: [start-runner]
runs-on: ${{ needs.start-runner.outputs.label }}
steps:
- name: prepare runner
run: |
sudo growpart /dev/nvme0n1 1
sudo resize2fs /dev/nvme0n1p1
- uses: actions/checkout@v2
- name: Retrieving coin apps
uses: actions/checkout@v2
with:
repository: LedgerHQ/coin-apps
token: ${{ secrets.PAT }}
path: coin-apps
- uses: actions/setup-node@master
with:
node-version: 14.x
- name: install yarn
run: npm i -g yarn
- name: pull docker image
run: docker pull ghcr.io/ledgerhq/speculos
- name: kill apt-get
run: sudo killall -w apt-get apt || echo OK
- name: Install linux deps
run: sudo apt-get install -y libusb-1.0-0-dev jq
- name: Install dependencies
run: |
yarn global add yalc
yarn --frozen-lockfile
yarn ci-setup-cli
- name: BOT
env:
SEED: ${{ secrets.SEED3 }}
BOT_REPORT_FOLDER: botreport
VERBOSE_FILE: botreport/logs.txt
GITHUB_SHA: ${GITHUB_SHA}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_RUN_ID: ${{ github.run_id }}
GITHUB_WORKFLOW: ${{ github.workflow }}
SLACK_API_TOKEN: ${{ secrets.SLACK_API_TOKEN }}
SLACK_CHANNEL: ci-sol-ll
BOT_FILTER_FAMILY: solana
run: mkdir botreport; COINAPPS=$PWD/coin-apps yarn ci-test-bot
timeout-minutes: 120
- name: Run coverage
if: failure() || success()
run: CODECOV_TOKEN=${{ secrets.CODECOV_TOKEN }} npx codecov
- name: upload logs
if: failure() || success()
uses: actions/upload-artifact@v1
with:
name: botreport
path: botreport/
18 changes: 18 additions & 0 deletions src/account/serialization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ import {
toCryptoOrgResourcesRaw,
fromCryptoOrgResourcesRaw,
} from "../families/crypto_org/serialization";

import {
toSolanaResourcesRaw,
fromSolanaResourcesRaw,
} from "../families/solana/serialization";

import {
getCryptoCurrencyById,
getTokenById,
Expand All @@ -68,6 +74,7 @@ export { toPolkadotResourcesRaw, fromPolkadotResourcesRaw };
export { toTezosResourcesRaw, fromTezosResourcesRaw };
export { toElrondResourcesRaw, fromElrondResourcesRaw };
export { toCryptoOrgResourcesRaw, fromCryptoOrgResourcesRaw };
export { toSolanaResourcesRaw, fromSolanaResourcesRaw };

export function toBalanceHistoryRaw(b: BalanceHistory): BalanceHistoryRaw {
return b.map(({ date, value }) => [date.toISOString(), value.toString()]);
Expand Down Expand Up @@ -707,6 +714,7 @@ export function fromAccountRaw(rawAccount: AccountRaw): Account {
polkadotResources,
elrondResources,
cryptoOrgResources,
solanaResources,
nfts,
} = rawAccount;
const subAccounts =
Expand Down Expand Up @@ -828,6 +836,10 @@ export function fromAccountRaw(rawAccount: AccountRaw): Account {
res.cryptoOrgResources = fromCryptoOrgResourcesRaw(cryptoOrgResources);
}

if (solanaResources) {
res.solanaResources = fromSolanaResourcesRaw(solanaResources);
}

return res;
}
export function toAccountRaw({
Expand Down Expand Up @@ -866,6 +878,7 @@ export function toAccountRaw({
polkadotResources,
elrondResources,
cryptoOrgResources,
solanaResources,
nfts,
}: Account): AccountRaw {
const res: AccountRaw = {
Expand Down Expand Up @@ -946,6 +959,11 @@ export function toAccountRaw({
if (cryptoOrgResources) {
res.cryptoOrgResources = toCryptoOrgResourcesRaw(cryptoOrgResources);
}

if (solanaResources) {
res.solanaResources = toSolanaResourcesRaw(solanaResources);
}

return res;
}

Expand Down
1 change: 1 addition & 0 deletions src/apps/support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const appVersionsRequired = {
Polkadot: ">= 11.9170.0",
Elrond: ">= 1.0.11",
Ethereum: ">= 1.9.17",
Solana: ">= 1.2.0",
};
export function mustUpgrade(
deviceModel: DeviceModelId,
Expand Down
5 changes: 5 additions & 0 deletions src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ const envDefinitions = {
def: "https://solana.coin.ledger.com",
desc: "proxy url for solana API",
},
SOLANA_VALIDATORS_APP_BASE_URL: {
parser: stringParser,
def: "http://validators-solana.coin.ledger.com/api/v1/validators/",
desc: "base url for validators.app validator list",
},
BASE_SOCKET_URL: {
def: "wss://scriptrunner.api.live.ledger.com/update",
parser: stringParser,
Expand Down
71 changes: 71 additions & 0 deletions src/families/bitcoin/__snapshots__/bridge.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -22955,6 +22955,77 @@ Array [
"type": "IN",
"value": "1000000",
},
],
Array [],
]
`;

exports[`solana currency bridge scanAccounts solana seed 1 1`] = `
Array [
Object {
"balance": "83389840",
"currencyId": "solana",
"derivationMode": "solanaMain",
"freshAddress": "AQbkEagmPgmsdAfS4X8V8UyJnXXjVPMvjeD15etqQ3Jh",
"freshAddressPath": "44'/501'",
"freshAddresses": Array [
Object {
"address": "AQbkEagmPgmsdAfS4X8V8UyJnXXjVPMvjeD15etqQ3Jh",
"derivationPath": "44'/501'",
},
],
"id": "js:2:solana:AQbkEagmPgmsdAfS4X8V8UyJnXXjVPMvjeD15etqQ3Jh:solanaMain",
"index": 0,
"name": "Solana 1",
"nfts": undefined,
"operationsCount": 2,
"pendingOperations": Array [],
"seedIdentifier": "AQbkEagmPgmsdAfS4X8V8UyJnXXjVPMvjeD15etqQ3Jh",
"solanaResources": Object {
"stakes": "[]",
},
"spendableBalance": "83389840",
"starred": false,
"swapHistory": Array [],
"syncHash": undefined,
"unitMagnitude": 9,
"used": true,
},
Object {
"balance": "0",
"currencyId": "solana",
"derivationMode": "solanaSub",
"freshAddress": "6rEgdtB3sgjKJnRE172YEr9z6qUyr4nFW28vJokuD36A",
"freshAddressPath": "44'/501'/0'",
"freshAddresses": Array [
Object {
"address": "6rEgdtB3sgjKJnRE172YEr9z6qUyr4nFW28vJokuD36A",
"derivationPath": "44'/501'/0'",
},
],
"id": "js:2:solana:6rEgdtB3sgjKJnRE172YEr9z6qUyr4nFW28vJokuD36A:solanaSub",
"index": 0,
"name": "Solana 1",
"nfts": undefined,
"operationsCount": 0,
"pendingOperations": Array [],
"seedIdentifier": "AQbkEagmPgmsdAfS4X8V8UyJnXXjVPMvjeD15etqQ3Jh",
"solanaResources": Object {
"stakes": "[]",
},
"spendableBalance": "0",
"starred": false,
"swapHistory": Array [],
"syncHash": undefined,
"unitMagnitude": 9,
"used": false,
},
]
`;

exports[`solana currency bridge scanAccounts solana seed 1 2`] = `
Array [
Array [
Object {
"accountId": "js:2:qtum:xpub6D97ABLAcapXNWjS2pNwYpmUjYYt5f2Tyj4PDSp7pvY2gySb2iAvejKNPm18raeU8WxtXVCpQfZjMN7eEdgtor8T5141ZLH7o2WkL1nyNQb:segwit",
"blockHash": "eb38de048b4f1a0b52cafb7ee7a6708bd02ccf59c77cadd3b0d078652e785abd",
Expand Down
40 changes: 40 additions & 0 deletions src/families/solana/api/cached.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const cacheKeyAddress = (address: string) => address;
const cacheKeyEmpty = () => "" as const;
const cacheKeyAssocTokenAccAddress = (owner: string, mint: string) =>
`${owner}:${mint}`;
const cacheKeyMinimumBalanceForRentExemption = (dataLengt: number) =>
dataLengt.toString();

const cacheKeyTransactions = (signatures: string[]) =>
hash([...signatures].sort());
Expand Down Expand Up @@ -63,6 +65,36 @@ export function cached(api: ChainAPI): ChainAPI {
minutes(1)
),

getStakeAccountsByStakeAuth: makeLRUCache(
api.getStakeAccountsByStakeAuth,
cacheKeyAddress,
minutes(1)
),

getStakeAccountsByWithdrawAuth: makeLRUCache(
api.getStakeAccountsByWithdrawAuth,
cacheKeyAddress,
minutes(1)
),

getStakeActivation: makeLRUCache(
api.getStakeActivation,
cacheKeyAddress,
minutes(1)
),

getInflationReward: makeLRUCache(
api.getInflationReward,
cacheKeyByArgs,
minutes(5)
),

getVoteAccounts: makeLRUCache(
api.getVoteAccounts,
cacheKeyEmpty,
minutes(1)
),

getRecentBlockhash: makeLRUCache(
api.getRecentBlockhash,
cacheKeyEmpty,
Expand All @@ -81,9 +113,17 @@ export function cached(api: ChainAPI): ChainAPI {
seconds(30)
),

getMinimumBalanceForRentExemption: makeLRUCache(
api.getMinimumBalanceForRentExemption,
cacheKeyMinimumBalanceForRentExemption,
minutes(5)
),

// do not cache
sendRawTransaction: api.sendRawTransaction,

getEpochInfo: makeLRUCache(api.getEpochInfo, cacheKeyEmpty, minutes(1)),

config: api.config,
};
}
6 changes: 5 additions & 1 deletion src/families/solana/api/chain/account/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
export { tryParseAsTokenAccount, parseTokenAccountInfo } from "./parser";
export {
tryParseAsTokenAccount,
parseTokenAccountInfo,
tryParseAsVoteAccount,
} from "./parser";
28 changes: 28 additions & 0 deletions src/families/solana/api/chain/account/parser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { ParsedAccountData } from "@solana/web3.js";
import { create } from "superstruct";
import { PARSED_PROGRAMS } from "../program/constants";
import { ParsedInfo } from "../validators";
import { StakeAccountInfo } from "./stake";
import { TokenAccount, TokenAccountInfo } from "./token";
import { VoteAccount, VoteAccountInfo } from "./vote";

export function parseTokenAccountInfo(info: unknown): TokenAccountInfo {
return create(info, TokenAccountInfo);
Expand All @@ -26,6 +29,31 @@ export function tryParseAsTokenAccount(
return onThrowReturnError(routine);
}

export function parseVoteAccountInfo(info: unknown): VoteAccountInfo {
return create(info, VoteAccountInfo);
}

export function tryParseAsVoteAccount(
data: ParsedAccountData
): VoteAccountInfo | undefined | Error {
const routine = () => {
const info = create(data.parsed, ParsedInfo);

if (data.program === PARSED_PROGRAMS.VOTE) {
const parsed = create(info, VoteAccount);
return parseVoteAccountInfo(parsed.info);
}

return undefined;
};

return onThrowReturnError(routine);
}

export function parseStakeAccountInfo(info: unknown): StakeAccountInfo {
return create(info, StakeAccountInfo);
}

function onThrowReturnError<R>(fn: () => R) {
try {
return fn();
Expand Down
Loading

0 comments on commit a63d453

Please sign in to comment.