diff --git a/README.md b/README.md index c31ead4..39e769a 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Check out the [full documentation](https://docs.kiln.fi/v1/connect/overview). - ADA - ATOM - DOT +- KSM - DYDX - ETH - FET diff --git a/package.json b/package.json index 4578c95..a55d22f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kilnfi/sdk", - "version": "2.17.3", + "version": "2.18.0", "autor": "Kiln (https://kiln.fi)", "license": "BUSL-1.1", "description": "JavaScript sdk for Kiln API", diff --git a/src/integrations/fb_signer.ts b/src/integrations/fb_signer.ts index 8c8c916..83b8133 100644 --- a/src/integrations/fb_signer.ts +++ b/src/integrations/fb_signer.ts @@ -12,7 +12,7 @@ import { utils } from "ethers"; import { EthTx } from "../types/eth"; import { MaticTx } from "../types/matic"; -type AssetId = +export type AssetId = | "SOL_TEST" | "SOL" | "ETH_TEST3" @@ -28,8 +28,8 @@ type AssetId = | "NEAR" | "XTZ_TEST" | "XTZ" - | "WND" | "DOT" + | "KSM" | "DV4TNT_TEST" | "DYDX_DYDX" | "CELESTIA" diff --git a/src/kiln.ts b/src/kiln.ts index b832d41..883101f 100644 --- a/src/kiln.ts +++ b/src/kiln.ts @@ -8,6 +8,7 @@ import { EthService } from "./services/eth"; import { FetService } from "./services/fet"; import { FireblocksService } from "./services/fireblocks"; import { InjService } from "./services/inj"; +import { KsmService } from "./services/ksm"; import { MaticService } from "./services/matic"; import { NearService } from "./services/near"; import { NobleService } from "./services/noble"; @@ -36,6 +37,7 @@ export class Kiln { ada: AdaService; near: NearService; dot: DotService; + ksm: KsmService; xtz: XtzService; matic: MaticService; osmo: OsmoService; @@ -60,6 +62,7 @@ export class Kiln { this.ada = new AdaService({ testnet }); this.near = new NearService({ testnet }); this.dot = new DotService({ testnet }); + this.ksm = new KsmService({ testnet }); this.xtz = new XtzService({ testnet }); this.matic = new MaticService({ testnet }); this.osmo = new OsmoService({ testnet }); diff --git a/src/services/dot.ts b/src/services/dot.ts index ababa8e..d97cd84 100644 --- a/src/services/dot.ts +++ b/src/services/dot.ts @@ -1,309 +1,25 @@ -import { Service } from "./service"; -import { DotRewardDestination, DotSignedTx, DotTx, DotTxHash, DotTxStatus } from "../types/dot"; -import { ServiceProps } from "../types/service"; -import { Integration } from "../types/integrations"; -import api from "../api"; -import { UnsignedTransaction } from "@substrate/txwrapper-polkadot"; import { parseUnits } from "viem"; +import { ServiceProps } from "../types/service"; +import { SubstrateService } from "./substrate"; /** * Staking docs: https://polkadot.js.org/docs/substrate/extrinsics#staking * Nomination pools docs: https://polkadot.js.org/docs/substrate/extrinsics#nominationpools */ -export class DotService extends Service { - constructor({ testnet }: ServiceProps) { - super({ testnet }); +export class DotService extends SubstrateService { + constructor(props: ServiceProps) { + super(props, "DOT"); } - /** - * Convert WND (testnet token) to PLANCK - * To be used in testnet (Westend) - * @param amountWnd - */ - wndToPlanck(amountWnd: string): string { - return parseUnits(amountWnd, 12).toString(); + mainToPlanck(amount: string): string { + return this.dotToPlanck(amount); } /** - * Convert DOT to PLANCK - * To be used in mainnet - * @param amountDot + * Convert DOT to planck + * @param amountDot amount in planck */ dotToPlanck(amountDot: string): string { return parseUnits(amountDot, 10).toString(); } - - /** - * Craft dot bonding transaction - * @param accountId id of the kiln account to use for the stake transaction - * @param stashAccount stash account address (your most secure cold wallet) - * @param amountDot amount to bond in DOT - * @param rewardDestination - */ - async craftBondTx( - accountId: string, - stashAccount: string, - amountDot: number, - rewardDestination: DotRewardDestination, - ): Promise { - const amountPlanck = this.testnet ? this.wndToPlanck(amountDot.toString()) : this.dotToPlanck(amountDot.toString()); - - const { data } = await api.post(`/v1/dot/transaction/bond`, { - account_id: accountId, - stash_account: stashAccount, - amount_planck: amountPlanck, - reward_destination: rewardDestination, - }); - return data; - } - - /** - * Craft dot bonding extra token transaction (to be used if you already bonded tokens) - * @param stashAccount stash account address - * @param amountDot amount to bond extra in DOT - */ - async craftBondExtraTx(stashAccount: string, amountDot: number): Promise { - const amountPlanck = this.testnet ? this.wndToPlanck(amountDot.toString()) : this.dotToPlanck(amountDot.toString()); - - const { data } = await api.post(`/v1/dot/transaction/bond-extra`, { - stash_account: stashAccount, - amount_planck: amountPlanck, - }); - return data; - } - - /** - * Craft dot rebond transaction (to be used to rebond unbonding token) - * @param stashAccount stash account address - * @param amountDot amount to rebond in DOT - */ - async craftRebondTx(stashAccount: string, amountDot: number): Promise { - const amountPlanck = this.testnet ? this.wndToPlanck(amountDot.toString()) : this.dotToPlanck(amountDot.toString()); - - const { data } = await api.post(`/v1/dot/transaction/rebond`, { - stash_account: stashAccount, - amount_planck: amountPlanck, - }); - return data; - } - - /** - * Craft dot nominate transaction - * @param stashAccount stash account address - * @param validatorAddresses validator addresses to nominate to - */ - async craftNominateTx(stashAccount: string, validatorAddresses: string[]): Promise { - const { data } = await api.post(`/v1/dot/transaction/nominate`, { - stash_account: stashAccount, - validator_addresses: validatorAddresses, - }); - return data; - } - - /** - * Craft dot unbonding transaction, there is an unbonding period before your tokens can be withdrawn - * @param stashAccount stash account address - * @param amountDot amount to unrebond in DOT - */ - async craftUnbondTx(stashAccount: string, amountDot: number): Promise { - const amountPlanck = this.testnet ? this.wndToPlanck(amountDot.toString()) : this.dotToPlanck(amountDot.toString()); - - const { data } = await api.post(`/v1/dot/transaction/unbond`, { - stash_account: stashAccount, - amount_planck: amountPlanck, - }); - return data; - } - - /** - * Craft dot withdraw unbonded token transaction - * @param stashAccount stash account address - */ - async craftWithdrawUnbondedTx(stashAccount: string): Promise { - const { data } = await api.post(`/v1/dot/transaction/withdraw-unbonded`, { - stash_account: stashAccount, - }); - return data; - } - - /** - * Craft dot chill transaction that chills the stash account, - * meaning that given account will not nominate - * any validator anymore, so you will stop earning rewards at the beginning - * of the next era. - * @param stashAccount stash account address - */ - async craftChillTx(stashAccount: string): Promise { - const { data } = await api.post(`/v1/dot/transaction/chill`, { - stash_account: stashAccount, - }); - return data; - } - - /** - * Craft dot set reward destination transaction that updates the destination rewards address for the given stash account - * @param stashAccount stash account address - * @param rewardsDestination: - * 'Staked': rewards are paid into the stash account, increasing the amount at stake accordingly. - * 'Stash': rewards are paid into the stash account, not increasing the amount at stake. - * 'Controller': rewards are paid into the controller account - * Custom account address: rewards are paid into the custom account address - */ - async craftSetPayeeTx(stashAccount: string, rewardsDestination: DotRewardDestination): Promise { - const { data } = await api.post(`/v1/dot/transaction/set-payee`, { - stash_account: stashAccount, - reward_destination: rewardsDestination, - }); - return data; - } - - /** - * Craft dot join pool transaction - * The amount to bond is transferred from the member to the pools account and immediately increases the pools bond. - * @param accountId - * @param memberAccount - * @param amountDot - * @param poolId - */ - async craftJoinPoolTx(accountId: string, memberAccount: string, amountDot: number, poolId: string): Promise { - const amountPlanck = this.testnet ? this.wndToPlanck(amountDot.toString()) : this.dotToPlanck(amountDot.toString()); - const { data } = await api.post(`/v1/dot/transaction/join-pool`, { - account_id: accountId, - member_account: memberAccount, - amount_planck: amountPlanck, - pool_id: poolId, - }); - return data; - } - - /** - * Craft a pool bond extra transaction - * Bond extra more funds from origin into the pool to which they already belong. - * Bonding extra funds implies an automatic payout of all pending rewards as well. - * @param memberAccount - * @param amountDot - */ - async craftBondExtraToPoolTx(memberAccount: string, amountDot: number): Promise { - const amountPlanck = this.testnet ? this.wndToPlanck(amountDot.toString()) : this.dotToPlanck(amountDot.toString()); - const { data } = await api.post(`/v1/dot/transaction/bond-extra-pool`, { - member_account: memberAccount, - amount_planck: amountPlanck, - }); - return data; - } - - /** - * Craft a pool bond extra transaction to bond available rewards into the pool to which they already belong. - * @param memberAccount - */ - async craftBondRewardsToPoolTx(memberAccount: string): Promise { - const { data } = await api.post(`/v1/dot/transaction/bond-rewards-pool`, { - member_account: memberAccount, - }); - return data; - } - - /** - * Craft a pool claim payout transaction - * A bonded member can use this to claim their payout based on the rewards that - * the pool has accumulated since their last claimed payout (OR since joining - * if this is their first time claiming rewards). - * The payout will be transferred to the member's account. - * The member will earn rewards pro rata based on the members stake vs the sum of the members in the pools stake. Rewards do not "expire". - * @param memberAccount - */ - async craftClaimPayoutFromPoolTx(memberAccount: string): Promise { - const { data } = await api.post(`/v1/dot/transaction/claim-payout-pool`, { - member_account: memberAccount, - }); - return data; - } - - /** - * Craft a pool unbond transaction - * Unbond amount funds from the pool. - * It implicitly collects the rewards one last time, since not doing so would mean some rewards would be forfeited. - * Warning: you cannot rebond during the unbonding period with a nomination pool. If you change your mind, you must wait for the unbonding period to end before you can join a nomination pool again. - * @param memberAccount - * @param amountDot - */ - async craftUnbondFromPoolTx(memberAccount: string, amountDot: number): Promise { - const amountPlanck = this.testnet ? this.wndToPlanck(amountDot.toString()) : this.dotToPlanck(amountDot.toString()); - const { data } = await api.post(`/v1/dot/transaction/unbond-pool`, { - member_account: memberAccount, - amount_planck: amountPlanck, - }); - return data; - } - - /** - * Craft a pool withdraw unbonded transaction - * Withdraw unbonded funds from member_account. - * @param memberAccount - */ - async craftWithdrawUnbondedFromPoolTx(memberAccount: string): Promise { - const { data } = await api.post(`/v1/dot/transaction/withdraw-unbonded-pool`, { - member_account: memberAccount, - }); - return data; - } - - /** - * Sign transaction with given integration - * @param integration custody solution to sign with - * @param tx raw transaction - * @param note note to identify the transaction in your custody solution - */ - async sign(integration: Integration, tx: DotTx, note?: string): Promise { - const payload = { - rawMessageData: { - messages: [ - { - content: tx.data.unsigned_tx_payload.substring(2), - }, - ], - }, - }; - - const fbSigner = this.getFbSigner(integration); - const fbNote = note ? note : "DOT tx from @kilnfi/sdk"; - const fbTx = await fbSigner.sign(payload, this.testnet ? "WND" : "DOT", fbNote); - const signature = `0x00${fbTx.signedMessages![0].signature.fullSig}`; - - const { data } = await api.post(`/v1/dot/transaction/prepare`, { - unsigned_tx_serialized: tx.data.unsigned_tx_serialized, - signature: signature, - }); - data.data.fireblocks_tx = fbTx; - return data; - } - - /** - * Broadcast signed transaction - * @param signedTx - */ - async broadcast(signedTx: DotSignedTx): Promise { - const { data } = await api.post(`/v1/dot/transaction/broadcast`, { - tx_serialized: signedTx.data.signed_tx_serialized, - }); - return data; - } - - /** - * Get transaction status - * @param txHash transaction hash - */ - async getTxStatus(txHash: string): Promise { - const { data } = await api.get(`/v1/dot/transaction/status?tx_hash=${txHash}`); - return data; - } - - /** - * Decode transaction - * @param txSerialized transaction serialized - */ - async decodeTx(txSerialized: string): Promise { - const { data } = await api.get(`/v1/dot/transaction/decode?tx_serialized=${txSerialized}`); - return data; - } } diff --git a/src/services/ksm.ts b/src/services/ksm.ts new file mode 100644 index 0000000..679a8c8 --- /dev/null +++ b/src/services/ksm.ts @@ -0,0 +1,25 @@ +import { parseUnits } from "viem"; +import { ServiceProps } from "../types/service"; +import { SubstrateService } from "./substrate"; + +/** + * Staking docs: https://polkadot.js.org/docs/substrate/extrinsics#staking + * Nomination pools docs: https://polkadot.js.org/docs/substrate/extrinsics#nominationpools + */ +export class KsmService extends SubstrateService { + constructor(props: ServiceProps) { + super(props, "KSM"); + } + + mainToPlanck(amount: string): string { + return this.ksmToPlanck(amount); + } + + /** + * Convert KSM to planck + * @param amountKsm amount in planck + */ + ksmToPlanck(amountKsm: string): string { + return parseUnits(amountKsm, 12).toString(); + } +} diff --git a/src/services/substrate.ts b/src/services/substrate.ts new file mode 100644 index 0000000..e4ec6a3 --- /dev/null +++ b/src/services/substrate.ts @@ -0,0 +1,317 @@ +import { UnsignedTransaction } from "@substrate/txwrapper-polkadot"; +import api from "../api"; +import { Integration } from "../types/integrations"; +import { ServiceProps } from "../types/service"; +import { + SubstrateRewardDestination, + SubstrateSignedTx, + SubstrateTx, + SubstrateTxHash, + SubstrateTxStatus, +} from "../types/substrate"; +import { Service } from "./service"; +import { AssetId } from "../integrations/fb_signer"; + +type SupportedTokens = ("DOT" | "KSM") & AssetId; + +/** + * Staking docs: https://polkadot.js.org/docs/substrate/extrinsics#staking + * Nomination pools docs: https://polkadot.js.org/docs/substrate/extrinsics#nominationpools + */ +export abstract class SubstrateService extends Service { + constructor( + { testnet }: ServiceProps, + private token: SupportedTokens, + ) { + super({ testnet }); + } + + /** + * Convert main token to planck + * @param amount amount in main token + */ + abstract mainToPlanck(amount: string): string; + + /** + * Craft bonding transaction + * @param accountId id of the kiln account to use for the stake transaction + * @param stashAccount stash account address (your most secure cold wallet) + * @param amount amount to bond in main unit (e.g. 1.2 DOT) + * @param rewardDestination + */ + async craftBondTx( + accountId: string, + stashAccount: string, + amount: number, + rewardDestination: SubstrateRewardDestination, + ): Promise { + const amountPlanck = this.mainToPlanck(amount.toString()); + + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/bond`, { + account_id: accountId, + stash_account: stashAccount, + amount_planck: amountPlanck, + reward_destination: rewardDestination, + }); + return data; + } + + /** + * Craft bonding extra token transaction (to be used if you already bonded tokens) + * @param stashAccount stash account address + * @param amount amount to bond extra in main unit (e.g. 1.2 DOT) + */ + async craftBondExtraTx(stashAccount: string, amount: number): Promise { + const amountPlanck = this.mainToPlanck(amount.toString()); + + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/bond-extra`, { + stash_account: stashAccount, + amount_planck: amountPlanck, + }); + return data; + } + + /** + * Craft rebond transaction (to be used to rebond unbonding token) + * @param stashAccount stash account address + * @param amount amount to rebond in main unit (e.g. 1.2 DOT) + */ + async craftRebondTx(stashAccount: string, amount: number): Promise { + const amountPlanck = this.mainToPlanck(amount.toString()); + + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/rebond`, { + stash_account: stashAccount, + amount_planck: amountPlanck, + }); + return data; + } + + /** + * Craft nominate transaction + * @param stashAccount stash account address + * @param validatorAddresses validator addresses to nominate to + */ + async craftNominateTx(stashAccount: string, validatorAddresses: string[]): Promise { + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/nominate`, { + stash_account: stashAccount, + validator_addresses: validatorAddresses, + }); + return data; + } + + /** + * Craft unbonding transaction, there is an unbonding period before your tokens can be withdrawn + * @param stashAccount stash account address + * @param amount amount to unrebond in main unit (e.g. 1.2 DOT) + */ + async craftUnbondTx(stashAccount: string, amount: number): Promise { + const amountPlanck = this.mainToPlanck(amount.toString()); + + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/unbond`, { + stash_account: stashAccount, + amount_planck: amountPlanck, + }); + return data; + } + + /** + * Craft withdraw unbonded token transaction + * @param stashAccount stash account address + */ + async craftWithdrawUnbondedTx(stashAccount: string): Promise { + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/withdraw-unbonded`, { + stash_account: stashAccount, + }); + return data; + } + + /** + * Craft chill transaction that chills the stash account, + * meaning that given account will not nominate + * any validator anymore, so you will stop earning rewards at the beginning + * of the next era. + * @param stashAccount stash account address + */ + async craftChillTx(stashAccount: string): Promise { + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/chill`, { + stash_account: stashAccount, + }); + return data; + } + + /** + * Craft set reward destination transaction that updates the destination rewards address for the given stash account + * @param stashAccount stash account address + * @param rewardsDestination: + * 'Staked': rewards are paid into the stash account, increasing the amount at stake accordingly. + * 'Stash': rewards are paid into the stash account, not increasing the amount at stake. + * 'Controller': rewards are paid into the controller account + * Custom account address: rewards are paid into the custom account address + */ + async craftSetPayeeTx(stashAccount: string, rewardsDestination: SubstrateRewardDestination): Promise { + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/set-payee`, { + stash_account: stashAccount, + reward_destination: rewardsDestination, + }); + return data; + } + + /** + * Craft join pool transaction + * The amount to bond is transferred from the member to the pools account and immediately increases the pools bond. + * @param accountId + * @param memberAccount + * @param amount + * @param poolId + */ + async craftJoinPoolTx( + accountId: string, + memberAccount: string, + amount: number, + poolId: string, + ): Promise { + const amountPlanck = this.mainToPlanck(amount.toString()); + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/join-pool`, { + account_id: accountId, + member_account: memberAccount, + amount_planck: amountPlanck, + pool_id: poolId, + }); + return data; + } + + /** + * Craft a pool bond extra transaction + * Bond extra more funds from origin into the pool to which they already belong. + * Bonding extra funds implies an automatic payout of all pending rewards as well. + * @param memberAccount + * @param amount + */ + async craftBondExtraToPoolTx(memberAccount: string, amount: number): Promise { + const amountPlanck = this.mainToPlanck(amount.toString()); + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/bond-extra-pool`, { + member_account: memberAccount, + amount_planck: amountPlanck, + }); + return data; + } + + /** + * Craft a pool bond extra transaction to bond available rewards into the pool to which they already belong. + * @param memberAccount + */ + async craftBondRewardsToPoolTx(memberAccount: string): Promise { + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/bond-rewards-pool`, { + member_account: memberAccount, + }); + return data; + } + + /** + * Craft a pool claim payout transaction + * A bonded member can use this to claim their payout based on the rewards that + * the pool has accumulated since their last claimed payout (OR since joining + * if this is their first time claiming rewards). + * The payout will be transferred to the member's account. + * The member will earn rewards pro rata based on the members stake vs the sum of the members in the pools stake. Rewards do not "expire". + * @param memberAccount + */ + async craftClaimPayoutFromPoolTx(memberAccount: string): Promise { + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/claim-payout-pool`, { + member_account: memberAccount, + }); + return data; + } + + /** + * Craft a pool unbond transaction + * Unbond amount funds from the pool. + * It implicitly collects the rewards one last time, since not doing so would mean some rewards would be forfeited. + * Warning: you cannot rebond during the unbonding period with a nomination pool. If you change your mind, you must wait for the unbonding period to end before you can join a nomination pool again. + * @param memberAccount + * @param amount + */ + async craftUnbondFromPoolTx(memberAccount: string, amount: number): Promise { + const amountPlanck = this.mainToPlanck(amount.toString()); + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/unbond-pool`, { + member_account: memberAccount, + amount_planck: amountPlanck, + }); + return data; + } + + /** + * Craft a pool withdraw unbonded transaction + * Withdraw unbonded funds from member_account. + * @param memberAccount + */ + async craftWithdrawUnbondedFromPoolTx(memberAccount: string): Promise { + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/withdraw-unbonded-pool`, { + member_account: memberAccount, + }); + return data; + } + + /** + * Sign transaction with given integration + * @param integration custody solution to sign with + * @param tx raw transaction + * @param note note to identify the transaction in your custody solution + */ + async sign(integration: Integration, tx: SubstrateTx, note?: string): Promise { + const payload = { + rawMessageData: { + messages: [ + { + content: tx.data.unsigned_tx_payload.substring(2), + }, + ], + }, + }; + + const fbSigner = this.getFbSigner(integration); + const fbNote = note ? note : `${this.token} tx from @kilnfi/sdk`; + const fbTx = await fbSigner.sign(payload, this.token, fbNote); + const signature = `0x00${fbTx.signedMessages![0].signature.fullSig}`; + + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/prepare`, { + unsigned_tx_serialized: tx.data.unsigned_tx_serialized, + signature: signature, + }); + data.data.fireblocks_tx = fbTx; + return data; + } + + /** + * Broadcast signed transaction + * @param signedTx + */ + async broadcast(signedTx: SubstrateSignedTx): Promise { + const { data } = await api.post(`/v1/${this.token.toLowerCase()}/transaction/broadcast`, { + tx_serialized: signedTx.data.signed_tx_serialized, + }); + return data; + } + + /** + * Get transaction status + * @param txHash transaction hash + */ + async getTxStatus(txHash: string): Promise { + const { data } = await api.get( + `/v1/${this.token.toLowerCase()}/transaction/status?tx_hash=${txHash}`, + ); + return data; + } + + /** + * Decode transaction + * @param txSerialized transaction serialized + */ + async decodeTx(txSerialized: string): Promise { + const { data } = await api.get( + `/v1/${this.token.toLowerCase()}/transaction/decode?tx_serialized=${txSerialized}`, + ); + return data; + } +} diff --git a/src/types/dot.ts b/src/types/substrate.ts similarity index 86% rename from src/types/dot.ts rename to src/types/substrate.ts index 810ce42..82b463e 100644 --- a/src/types/dot.ts +++ b/src/types/substrate.ts @@ -7,9 +7,9 @@ import { TransactionResponse } from "fireblocks-sdk"; * 'Controller': Rewards are paid into the controller account * Custom account address: Rewards are paid into the custom account address */ -export type DotRewardDestination = "Staked" | "Stash" | "Controller" | string; +export type SubstrateRewardDestination = "Staked" | "Stash" | "Controller" | string; -export type DotTx = { +export type SubstrateTx = { data: { unsigned_tx_payload: string; unsigned_tx_serialized: string; @@ -17,20 +17,20 @@ export type DotTx = { }; }; -export type DotSignedTx = { +export type SubstrateSignedTx = { data: { fireblocks_tx: TransactionResponse; signed_tx_serialized: string; }; }; -export type DotTxHash = { +export type SubstrateTxHash = { data: { tx_hash: string; }; }; -export type DotTxStatus = { +export type SubstrateTxStatus = { code: number; message: string; generated_at: string; diff --git a/src/validators.ts b/src/validators.ts index 489128c..b8f8b3f 100644 --- a/src/validators.ts +++ b/src/validators.ts @@ -22,6 +22,12 @@ export const KILN_VALIDATORS = { KILN_NOMINATION_POOL_ID: "118", }, }, + KSM: { + mainnet: { + KILN: "FV3za2fceAXtw4KwVnPJK4c4Y2ph8VNMEA26MkgjTaEA76u", + KILN_NOMINATION_POOL_ID: "131", + }, + }, MATIC: { mainnet: { KILN_OWNEST: "0xD14a87025109013B0a2354a775cB335F926Af65A", @@ -57,4 +63,9 @@ export const KILN_VALIDATORS = { KILN: "fetchvaloper146mj09yzu3mvz7pmy4dvs4z9wr2mst7ryjvncp", }, }, + ZETA: { + mainnet: { + KILN: "zetavaloper1u9xeaqdjz3kky2ymdhdsn0ra5uy9tc3ep3yfhe", + }, + }, };