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

Solana staking #1844

Merged
merged 92 commits into from
Apr 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
c93f6c1
solana add initial staking support
konoart Dec 15, 2021
cb5f919
solana improve staking
konoart Dec 15, 2021
a47a769
solana fix typos
konoart Dec 15, 2021
e2e48b6
solana fix cli format for staking
konoart Dec 15, 2021
9bf50ca
solana add device fields for stake create acc
konoart Dec 15, 2021
84a9e0d
solana add stake delegate support
konoart Dec 16, 2021
98b45a3
solana fix lint
konoart Dec 16, 2021
9bee86b
solana add stake undelegate
konoart Dec 16, 2021
a942683
solana add stake withdraw
konoart Dec 16, 2021
e394c2a
solana add stake split
konoart Dec 16, 2021
b762dc7
solana add stakes loading
konoart Dec 20, 2021
1b8e825
solana improve staking
konoart Dec 20, 2021
48d4216
solana introduce solana resources
konoart Dec 20, 2021
918542f
solana add preload data
konoart Dec 20, 2021
7d380e3
solana add hydrate to bridge
konoart Dec 21, 2021
2995647
solana add stake actions
konoart Dec 22, 2021
087dd98
solana improve staking
konoart Dec 27, 2021
78fed9f
solana add meta to validators
konoart Dec 27, 2021
b18229f
solana add validator name
konoart Dec 27, 2021
2d0fae1
solana fix seed for stake accs
konoart Dec 29, 2021
110a3ae
solana add stake reward
konoart Dec 29, 2021
2555e1b
Merge remote-tracking branch 'upstream/master' into solana-integration-3
konoart Feb 2, 2022
ff3ba5f
solana improve staking
konoart Feb 9, 2022
393ba90
solana stake add withdrawable amount
konoart Feb 9, 2022
7b682b3
Merge remote-tracking branch 'upstream/master' into solana-integration-3
konoart Feb 14, 2022
fd91542
solana refactor framework
konoart Feb 21, 2022
ea7c6ee
solana fix tests
konoart Feb 21, 2022
0905fb9
solana make auto delegation mandatory
konoart Feb 22, 2022
d3bc0d0
solana sort stakes
konoart Feb 22, 2022
4c54f28
solana fix error key
konoart Feb 22, 2022
35e4f96
solana add delegation validator validation
konoart Feb 22, 2022
03999be
solana add staking create acc tests
konoart Feb 23, 2022
4ede14c
solana add staking delegate tests
konoart Feb 23, 2022
e43a1d9
solana add stake undelegate tests
konoart Feb 23, 2022
05df678
solana remove redundant checks for stake delegation
konoart Feb 23, 2022
4fb41e3
solana skip options validations on cli level
konoart Feb 23, 2022
3f18224
solana skip undelegate options validations on cli level
konoart Feb 23, 2022
9526658
solana improve staking tests
konoart Feb 24, 2022
286e9fd
solana add delegatable check to staking
konoart Feb 24, 2022
813d400
solana fix estimate max spendable
konoart Feb 25, 2022
0eef4d5
solana add delegation active test
konoart Feb 28, 2022
4ab7f0c
solana add stake state tests
konoart Mar 1, 2022
56bd5ce
Merge remote-tracking branch 'upstream/master' into solana-integration-3
konoart Mar 14, 2022
b9aa1d1
solana introduce validators app validators
konoart Mar 14, 2022
849d0c4
solana add validators for testnet & devnet
konoart Mar 15, 2022
87a7834
solana refactor validators app validators
konoart Mar 15, 2022
368b651
solana update meta of stakes
konoart Mar 16, 2022
b2e105f
Merge remote-tracking branch 'upstream/develop' into solana-integrati…
konoart Mar 16, 2022
2b70c7c
solana update sort order of stakes
konoart Mar 17, 2022
8b73294
solana add delegated op type
konoart Mar 18, 2022
f717075
solana shuffle staking validators
konoart Mar 21, 2022
f79485b
solana fix stake withdraw optimistic value
konoart Mar 21, 2022
b42e10a
solana clean comments
konoart Mar 21, 2022
39fddd3
Merge remote-tracking branch 'upstream/develop' into solana-integrati…
konoart Mar 22, 2022
7bc4a16
Merge remote-tracking branch 'upstream/develop' into solana-integrati…
konoart Mar 22, 2022
e4c3ca4
solana update mock data
konoart Mar 23, 2022
7b373af
solana add initial staking bot specs
konoart Mar 25, 2022
8c51b07
solana add staking bot specs
konoart Mar 28, 2022
3a94754
solana move ledger vote acc to utils
konoart Mar 29, 2022
c77c897
solana add swap util
konoart Mar 29, 2022
8d5c0f5
solana update device tx config
konoart Mar 30, 2022
c6045a2
solana fix lint
konoart Mar 30, 2022
39968b3
Add bot for Solana
hakim-adamik Apr 1, 2022
d70cf09
Solana staking integration (#1825)
konoart Apr 1, 2022
d336364
Change seed for Solana bot
hakim-adamik Apr 1, 2022
72555ef
Merge remote-tracking branch 'ledgerhq/family/solana' into family/solana
hakim-adamik Apr 1, 2022
f15ab31
Change seed again for Solana bot
hakim-adamik Apr 1, 2022
5d40333
trigger bot
hakim-adamik Apr 1, 2022
51a980c
solana add stake percent calc fn
konoart Apr 1, 2022
9092859
solana update spec for new nano app
konoart Apr 4, 2022
1f119d0
solana set minimum required nano app version
konoart Apr 4, 2022
2afd31a
solana add validators app url env variable
konoart Apr 4, 2022
12750d6
Merge remote-tracking branch 'konoart/solana-integration-3' into HEAD
hakim-adamik Apr 4, 2022
4edd965
fix bad merge
hakim-adamik Apr 4, 2022
6f3754c
trigger bot
hakim-adamik Apr 4, 2022
d2a53f7
trigger bot
hakim-adamik Apr 4, 2022
4831074
trigger bot
hakim-adamik Apr 4, 2022
5838ad3
trigger bot
hakim-adamik Apr 5, 2022
e80b206
Solana bot - increase timeout and decrease minimum to delegate
hakim-adamik Apr 5, 2022
37b3003
trigger bot
hakim-adamik Apr 5, 2022
b575c03
trigger bot
hakim-adamik Apr 5, 2022
5cd3411
trigger bot
hakim-adamik Apr 5, 2022
8341101
trigger bot
hakim-adamik Apr 5, 2022
8cedc0a
Merge remote-tracking branch 'ledgerhq/develop' into HEAD
hakim-adamik Apr 5, 2022
9b83a10
Setup the bot to not use the validators.app proxy (yet)
hakim-adamik Apr 5, 2022
b868723
Merge remote-tracking branch 'ledgerhq/develop' into HEAD
hakim-adamik Apr 5, 2022
025fde3
Replace all deprecated uses of open(deviceId) with withDevice
hakim-adamik Apr 5, 2022
ef3c2b4
Solana - replace open(deviceId) with withDevice
hakim-adamik Apr 5, 2022
320a7e8
Remove custom data
hakim-adamik Apr 7, 2022
fd0e165
Merge remote-tracking branch 'origin/release/v22.0.0' into family/solana
lambertkevin Apr 7, 2022
302dd39
Update solana bot
hakim-adamik Apr 7, 2022
6936144
Merge remote-tracking branch 'ledgerhq/family/solana' into HEAD
hakim-adamik Apr 7, 2022
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
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