Skip to content

Commit 6909ce0

Browse files
authored
add bridge usdc endpoints (#93)
* add bridge usdc endpoints * rename
1 parent 491227d commit 6909ce0

File tree

4 files changed

+183
-2
lines changed

4 files changed

+183
-2
lines changed

src/kiln.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { OsmoService } from './services/osmo';
1313
import { FireblocksService } from "./services/fireblocks";
1414
import { DydxService } from "./services/dydx";
1515
import { TiaService } from "./services/tia";
16+
import { NobleService } from "./services/noble";
1617

1718
type Config = {
1819
apiToken: string;
@@ -36,6 +37,7 @@ export class Kiln {
3637
osmo: OsmoService;
3738
dydx: DydxService;
3839
tia: TiaService;
40+
noble: NobleService;
3941

4042
constructor({ testnet, apiToken, baseUrl }: Config) {
4143
api.defaults.headers.common.Authorization = `Bearer ${apiToken}`;
@@ -58,5 +60,6 @@ export class Kiln {
5860
this.osmo = new OsmoService({ testnet });
5961
this.dydx = new DydxService({ testnet });
6062
this.tia = new TiaService({ testnet });
63+
this.noble = new NobleService({ testnet });
6164
}
6265
}

src/services/dydx.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ServiceProps } from '../types/service';
44
import { Integration } from '../types/integrations';
55
import api from '../api';
66
import { DecodedTxRaw } from "@cosmjs/proto-signing";
7-
import { CosmosSignedTx, CosmosTx, CosmosTxHash, CosmosTxStatus } from "../types/cosmos";
7+
import { Balance, CosmosSignedTx, CosmosTx, CosmosTxHash, CosmosTxStatus } from "../types/cosmos";
88

99
export class DydxService extends Service {
1010

@@ -20,6 +20,10 @@ export class DydxService extends Service {
2020
return (parseFloat(amountDydx) * 10 ** 18).toFixed();
2121
}
2222

23+
usdcToUusdc(amountUsdc: string): string {
24+
return (parseFloat(amountUsdc) * 10 ** 6).toFixed();
25+
}
26+
2327
/**
2428
* Craft dydx staking transaction
2529
* @param accountId id of the kiln account to use for the stake transaction
@@ -118,6 +122,44 @@ export class DydxService extends Service {
118122

119123
}
120124

125+
/**
126+
* Transfer IBC USDC from your account to your NOBLE account
127+
* @param pubkey
128+
* @param amountUsdc
129+
*/
130+
async craftTransferIbcUsdc(
131+
pubkey: string,
132+
amountUsdc: number,
133+
): Promise<CosmosTx> {
134+
135+
const { data } = await api.post<CosmosTx>(
136+
`/v1/dydx/transaction/ibc-transfer-usdc`,
137+
{
138+
pubkey: pubkey,
139+
amount_uusdc: this.usdcToUusdc(amountUsdc.toString()),
140+
});
141+
return data;
142+
}
143+
144+
/**
145+
* Get balance of given address for given denom (ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5 for USDC on DYDX)
146+
* @param address
147+
* @param denom
148+
*/
149+
async getBalance(
150+
address: string,
151+
denom: string,
152+
): Promise<Balance> {
153+
154+
const { data } = await api.post<Balance>(
155+
`/v1/dydx/balance`,
156+
{
157+
address,
158+
denom
159+
});
160+
return data;
161+
}
162+
121163
/**
122164
* Sign transaction with given integration
123165
* @param integration custody solution to sign with

src/services/noble.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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 { Balance, CosmosSignedTx, CosmosTx, CosmosTxHash, CosmosTxStatus } from "../types/cosmos";
8+
9+
export class NobleService extends Service {
10+
11+
constructor({ testnet }: ServiceProps) {
12+
super({ testnet });
13+
}
14+
15+
usdcToUusdc(amountUsdc: string): string {
16+
return (parseFloat(amountUsdc) * 10 ** 6).toFixed();
17+
}
18+
19+
/**
20+
* Get balance of given address for given denom (uusdc on NOBLE)
21+
* @param address
22+
* @param denom
23+
*/
24+
async getBalance(
25+
address: string,
26+
denom: string,
27+
): Promise<Balance> {
28+
29+
const { data } = await api.post<Balance>(
30+
`/v1/noble/balance`,
31+
{
32+
address,
33+
denom
34+
});
35+
return data;
36+
}
37+
38+
/**
39+
* Burn noble USDC to it can be minted on Ethereum
40+
* @param pubkey
41+
* @param recipient
42+
* @param amountUsdc
43+
*/
44+
async craftBurnUsdc(
45+
pubkey: string,
46+
recipient: string,
47+
amountUsdc: number,
48+
): Promise<CosmosTx> {
49+
50+
const { data } = await api.post<CosmosTx>(
51+
`/v1/noble/transaction/burn-usdc`,
52+
{
53+
pubkey: pubkey,
54+
recipient: recipient,
55+
amount_uusdc: this.usdcToUusdc(amountUsdc.toString()),
56+
});
57+
return data;
58+
}
59+
60+
/**
61+
* Sign transaction with given integration
62+
* @param integration custody solution to sign with
63+
* @param tx raw transaction
64+
* @param note note to identify the transaction in your custody solution
65+
*/
66+
async sign(integration: Integration, tx: CosmosTx, note?: string): Promise<CosmosSignedTx> {
67+
const payload = {
68+
rawMessageData: {
69+
messages: [
70+
{
71+
'content': tx.data.unsigned_tx_hash,
72+
},
73+
],
74+
},
75+
};
76+
const fbNote = note ? note : 'NOBLE tx from @kilnfi/sdk';
77+
const signer = this.getFbSigner(integration);
78+
// NOBLE chain is not supported by Fireblocks, so we use DYDX_DYDX
79+
const fbTx = await signer.signWithFB(payload, 'DYDX_DYDX', fbNote);
80+
const signature: string = fbTx.signedMessages![0].signature.fullSig;
81+
const { data } = await api.post<CosmosSignedTx>(
82+
`/v1/noble/transaction/prepare`,
83+
{
84+
pubkey: tx.data.pubkey,
85+
tx_body: tx.data.tx_body,
86+
tx_auth_info: tx.data.tx_auth_info,
87+
signature: signature,
88+
});
89+
data.data.fireblocks_tx = fbTx;
90+
return data;
91+
}
92+
93+
94+
/**
95+
* Broadcast transaction to the network
96+
* @param signedTx
97+
*/
98+
async broadcast(signedTx: CosmosSignedTx): Promise<CosmosTxHash> {
99+
100+
const { data } = await api.post<CosmosTxHash>(
101+
`/v1/noble/transaction/broadcast`,
102+
{
103+
tx_serialized: signedTx.data.signed_tx_serialized,
104+
});
105+
return data;
106+
107+
}
108+
109+
/**
110+
* Get transaction status
111+
* @param txHash
112+
*/
113+
async getTxStatus(txHash: string): Promise<CosmosTxStatus> {
114+
115+
const { data } = await api.get<CosmosTxStatus>(
116+
`/v1/noble/transaction/status?tx_hash=${txHash}`);
117+
return data;
118+
119+
}
120+
121+
/**
122+
* Decode transaction
123+
* @param txSerialized transaction serialized
124+
*/
125+
async decodeTx(txSerialized: string): Promise<DecodedTxRaw> {
126+
127+
const { data } = await api.get<DecodedTxRaw>(
128+
`/v1/noble/transaction/decode?tx_serialized=${txSerialized}`);
129+
return data;
130+
131+
}
132+
}

src/types/cosmos.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IndexedTx, StdFee } from "@cosmjs/stargate";
1+
import { Coin, IndexedTx, StdFee } from "@cosmjs/stargate";
22
import { EncodeObject } from "@cosmjs/proto-signing";
33
import { TransactionResponse } from "fireblocks-sdk";
44

@@ -32,4 +32,8 @@ export type CosmosTxStatus = {
3232
status: 'success' | 'error',
3333
receipt: IndexedTx | null,
3434
}
35+
}
36+
37+
export type Balance = {
38+
data: Coin;
3539
}

0 commit comments

Comments
 (0)