Skip to content

Commit d56cb86

Browse files
authored
add kava (#112)
* add kava * update readme * nit * nit * nit
1 parent 9840226 commit d56cb86

File tree

4 files changed

+184
-2
lines changed

4 files changed

+184
-2
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ Check out the [full documentation](https://docs.kiln.fi/v1/connect/overview).
1111
- ADA
1212
- ATOM
1313
- DOT
14-
- KSM
1514
- DYDX
1615
- ETH
1716
- FET
1817
- INJ
18+
- KAVA
19+
- KSM
1920
- MATIC
2021
- NEAR
2122
- NOBLE

src/integrations/fb_signer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ export type AssetId =
3535
| "CELESTIA"
3636
| "INJ_INJ"
3737
| "TON_TEST"
38-
| "TON";
38+
| "TON"
39+
| "KAVA_KAVA";
3940

4041
export class FbSigner {
4142
protected fireblocks: FireblocksSDK;

src/kiln.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { TonService } from "./services/ton";
1919
import { XtzService } from "./services/xtz";
2020
import { ZetaService } from "./services/zeta";
2121
import { KILN_VALIDATORS as v } from "./validators";
22+
import { KavaService } from "./services/kava";
2223

2324
type Config = {
2425
apiToken: string;
@@ -48,6 +49,7 @@ export class Kiln {
4849
inj: InjService;
4950
ton: TonService;
5051
zeta: ZetaService;
52+
kava: KavaService;
5153

5254
constructor({ testnet, apiToken, baseUrl }: Config) {
5355
api.defaults.headers.common.Authorization = `Bearer ${apiToken}`;
@@ -73,5 +75,6 @@ export class Kiln {
7375
this.inj = new InjService({ testnet });
7476
this.ton = new TonService({ testnet });
7577
this.zeta = new ZetaService({ testnet });
78+
this.kava = new KavaService({ testnet });
7679
}
7780
}

src/services/kava.ts

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import { Service } from "./service";
2+
3+
import { ServiceProps } from "../types/service";
4+
import { Integration } from "../types/integrations";
5+
import api from "../api";
6+
import { DecodedTxRaw } from "@cosmjs/proto-signing";
7+
import { CosmosSignedTx, CosmosTx, CosmosTxHash, CosmosTxStatus } from "../types/cosmos";
8+
import { parseUnits } from "viem";
9+
10+
export class KavaService extends Service {
11+
constructor({ testnet }: ServiceProps) {
12+
super({ testnet });
13+
}
14+
15+
/**
16+
* Convert KAVA to ukava
17+
* @param amount
18+
*/
19+
kavaToUkava(amount: string): string {
20+
return parseUnits(amount, 6).toString();
21+
}
22+
23+
/**
24+
* Craft kava staking transaction
25+
* @param accountId id of the kiln account to use for the stake transaction
26+
* @param pubkey wallet pubkey, this is different from the wallet address
27+
* @param validatorAddress validator address to delegate to
28+
* @param amountKava how many tokens to stake in KAVA
29+
* @param restakeRewards If enabled, the rewards will be automatically restaked
30+
* @param granteeAddress validator grantee address
31+
*/
32+
async craftStakeTx(
33+
accountId: string,
34+
pubkey: string,
35+
validatorAddress: string,
36+
amountKava: number,
37+
restakeRewards: boolean = false,
38+
granteeAddress?: string,
39+
): Promise<CosmosTx> {
40+
const { data } = await api.post<CosmosTx>(`/v1/kava/transaction/stake`, {
41+
account_id: accountId,
42+
pubkey: pubkey,
43+
validator: validatorAddress,
44+
amount_ukava: this.kavaToUkava(amountKava.toString()),
45+
restake_rewards: restakeRewards,
46+
grantee_address: granteeAddress,
47+
});
48+
return data;
49+
}
50+
51+
/**
52+
* Craft kava withdraw rewards transaction
53+
* @param pubkey wallet pubkey, this is different from the wallet address
54+
* @param validatorAddress validator address to which the delegation has been made
55+
*/
56+
async craftWithdrawRewardsTx(pubkey: string, validatorAddress: string): Promise<CosmosTx> {
57+
const { data } = await api.post<CosmosTx>(`/v1/kava/transaction/withdraw-rewards`, {
58+
pubkey: pubkey,
59+
validator: validatorAddress,
60+
});
61+
return data;
62+
}
63+
64+
/**
65+
* Craft kava restake rewards transaction
66+
* @param pubkey wallet pubkey, this is different from the wallet address
67+
* @param validatorAddress validator address to which the delegation has been made
68+
* @param granteeAddress validator grantee address
69+
*/
70+
async craftRestakeRewardsTx(pubkey: string, validatorAddress: string, granteeAddress: string): Promise<CosmosTx> {
71+
const { data } = await api.post<CosmosTx>(`/v1/kava/transaction/restake-rewards`, {
72+
pubkey: pubkey,
73+
validator_address: validatorAddress,
74+
grantee_address: granteeAddress,
75+
});
76+
return data;
77+
}
78+
79+
/**
80+
* Craft kava unstaking transaction
81+
* @param pubkey wallet pubkey, this is different from the wallet address
82+
* @param validatorAddress validator address to which the delegation has been made
83+
* @param amountKava how many tokens to undelegate in KAVA
84+
*/
85+
async craftUnstakeTx(pubkey: string, validatorAddress: string, amountKava?: number): Promise<CosmosTx> {
86+
const { data } = await api.post<CosmosTx>(`/v1/kava/transaction/unstake`, {
87+
pubkey: pubkey,
88+
validator: validatorAddress,
89+
amount_kava: amountKava ? this.kavaToUkava(amountKava.toString()) : undefined,
90+
});
91+
return data;
92+
}
93+
94+
/**
95+
* Craft kava redelegate transaction
96+
* @param accountId id of the kiln account to use for the new stake
97+
* @param pubkey wallet pubkey, this is different from the wallet address
98+
* @param validatorSourceAddress validator address of the current delegation
99+
* @param validatorDestinationAddress validator address to which the delegation will be moved
100+
* @param amountKava how many tokens to redelegate in KAVA
101+
*/
102+
async craftRedelegateTx(
103+
accountId: string,
104+
pubkey: string,
105+
validatorSourceAddress: string,
106+
validatorDestinationAddress: string,
107+
amountKava?: number,
108+
): Promise<CosmosTx> {
109+
const { data } = await api.post<CosmosTx>(`/v1/kava/transaction/redelegate`, {
110+
account_id: accountId,
111+
pubkey: pubkey,
112+
validator_source: validatorSourceAddress,
113+
validator_destination: validatorDestinationAddress,
114+
amount_ukava: amountKava ? this.kavaToUkava(amountKava.toString()) : undefined,
115+
});
116+
return data;
117+
}
118+
119+
/**
120+
* Sign transaction with given integration
121+
* @param integration custody solution to sign with
122+
* @param tx raw transaction
123+
* @param note note to identify the transaction in your custody solution
124+
*/
125+
async sign(integration: Integration, tx: CosmosTx, note?: string): Promise<CosmosSignedTx> {
126+
const payload = {
127+
rawMessageData: {
128+
messages: [
129+
{
130+
content: tx.data.unsigned_tx_hash,
131+
},
132+
],
133+
},
134+
};
135+
const fbNote = note ? note : "KAVA tx from @kilnfi/sdk";
136+
const signer = this.getFbSigner(integration);
137+
const fbTx = await signer.sign(payload, "KAVA_KAVA", fbNote);
138+
const signature: string = fbTx.signedMessages![0].signature.fullSig;
139+
const { data } = await api.post<CosmosSignedTx>(`/v1/kava/transaction/prepare`, {
140+
pubkey: tx.data.pubkey,
141+
tx_body: tx.data.tx_body,
142+
tx_auth_info: tx.data.tx_auth_info,
143+
signature: signature,
144+
});
145+
data.data.fireblocks_tx = fbTx;
146+
return data;
147+
}
148+
149+
/**
150+
* Broadcast transaction to the network
151+
* @param signedTx
152+
*/
153+
async broadcast(signedTx: CosmosSignedTx): Promise<CosmosTxHash> {
154+
const { data } = await api.post<CosmosTxHash>(`/v1/kava/transaction/broadcast`, {
155+
tx_serialized: signedTx.data.signed_tx_serialized,
156+
});
157+
return data;
158+
}
159+
160+
/**
161+
* Get transaction status
162+
* @param txHash
163+
*/
164+
async getTxStatus(txHash: string): Promise<CosmosTxStatus> {
165+
const { data } = await api.get<CosmosTxStatus>(`/v1/kava/transaction/status?tx_hash=${txHash}`);
166+
return data;
167+
}
168+
169+
/**
170+
* Decode transaction
171+
* @param txSerialized transaction serialized
172+
*/
173+
async decodeTx(txSerialized: string): Promise<DecodedTxRaw> {
174+
const { data } = await api.get<DecodedTxRaw>(`/v1/kava/transaction/decode?tx_serialized=${txSerialized}`);
175+
return data;
176+
}
177+
}

0 commit comments

Comments
 (0)