Skip to content

Commit 8fd62df

Browse files
authored
Merge pull request #102 from kilnfi/zeta-support
sdk-js: ZETA support
2 parents 62dd194 + c399fdb commit 8fd62df

File tree

4 files changed

+182
-3
lines changed

4 files changed

+182
-3
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Check out the [full documentation](https://docs.kiln.fi/v1/connect/overview).
2323
- TIA
2424
- TON
2525
- XTZ
26+
- ZETA
2627
- More protocol to come, don't hesitate to contact us ([email protected])
2728

2829
### ⚠️️WARNING:

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@kilnfi/sdk",
3-
"version": "2.15.0",
3+
"version": "2.16.0",
44
"autor": "Kiln <[email protected]> (https://kiln.fi)",
55
"license": "BUSL-1.1",
66
"description": "JavaScript sdk for Kiln API",

src/kiln.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,17 @@ import { DydxService } from "./services/dydx";
77
import { EthService } from "./services/eth";
88
import { FetService } from "./services/fet";
99
import { FireblocksService } from "./services/fireblocks";
10+
import { InjService } from "./services/inj";
1011
import { MaticService } from "./services/matic";
1112
import { NearService } from "./services/near";
1213
import { NobleService } from "./services/noble";
1314
import { OsmoService } from "./services/osmo";
1415
import { SolService } from "./services/sol";
1516
import { TiaService } from "./services/tia";
17+
import { TonService } from "./services/ton";
1618
import { XtzService } from "./services/xtz";
19+
import { ZetaService } from "./services/zeta";
1720
import { KILN_VALIDATORS as v } from "./validators";
18-
import { InjService } from "./services/inj";
19-
import { TonService } from "./services/ton";
2021

2122
type Config = {
2223
apiToken: string;
@@ -44,6 +45,7 @@ export class Kiln {
4445
fet: FetService;
4546
inj: InjService;
4647
ton: TonService;
48+
zeta: ZetaService;
4749

4850
constructor({ testnet, apiToken, baseUrl }: Config) {
4951
api.defaults.headers.common.Authorization = `Bearer ${apiToken}`;
@@ -67,5 +69,6 @@ export class Kiln {
6769
this.fet = new FetService({ testnet });
6870
this.inj = new InjService({ testnet });
6971
this.ton = new TonService({ testnet });
72+
this.zeta = new ZetaService({ testnet });
7073
}
7174
}

src/services/zeta.ts

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

0 commit comments

Comments
 (0)