Skip to content

Commit c41cab2

Browse files
committed
Use api as proxy to the fireblocks api requests
Fixing types on transsaction request Fix Base url path on FireblocksService Add Fireblocks wallet button and NoWalletPegin form I've defined a new wallet button for fireblocks on pegin, it is connected to a new view to create a pegin tx with no wallet previously connected Finish Flyover flow using fireblocks on POC Remove home buttons and rename Fireblocks form buttons Remove native option Accepting quote and using lps destination address Check user privileges before enable the peginForm on fireblocks Fix error handling on the api user role Increase app version to 3.2 Remove IBI console Include JWT build function to create the fireblocks request on the UI I've defined the JWT creation method using the provede .key file and the defined methods in the FireblocksService in order to prevent sending credentials to the backend Update Fireblocks service to create the JWT on the ui Avoid use of Math.random in the txIdGenerator Include Vault selector for the Fireblock account
1 parent 9df5c6c commit c41cab2

File tree

23 files changed

+1105
-73
lines changed

23 files changed

+1105
-73
lines changed

package-lock.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/App.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export default {
8989
script-src 'self' 'nonce-${vuetifyNonce}' 'unsafe-eval';
9090
script-src-elem 'self' 'unsafe-inline' https://script.hotjar.com https://www.clarity.ms/s/* https://static.hotjar.com https://*.hotjar.com https://*.hotjar.io https://api.coingecko.com/ https://*.clarity.ms https://www.clarity.ms/ https://www.gstatic.com/ https://www.google.com/recaptcha/;
9191
img-src data: https: data: blob: https://walletconnect.org https://walletconnect.com https://secure.walletconnect.com https://secure.walletconnect.org;
92-
connect-src 'self' 'unsafe-inline' https://www.google.com/recaptcha/ https://www.clarity.ms/s/0.7.16/clarity.js wss://* https://*.hotjar.com https://*.hotjar.io https://www.clarity.ms/s/* wss://*.hotjar.com ${envVariables.vueAppApiBaseUrl} ${envVariables.vueAppRskNodeHost} ${envVariables.cspConfiguration} https://api.coingecko.com/ https://*.clarity.ms https://www.clarity.ms/* https://rpc.walletconnect.com https://rpc.walletconnect.org https://relay.walletconnect.com https://relay.walletconnect.org wss://relay.walletconnect.com wss://relay.walletconnect.org https://pulse.walletconnect.com https://pulse.walletconnect.org https://api.web3modal.com https://api.web3modal.org https://public-node.testnet.rsk.co/ https://public-node.rsk.co https://mempool.space;
92+
connect-src 'self' 'unsafe-inline' https://www.google.com/recaptcha/ https://www.clarity.ms/s/0.7.16/clarity.js wss://* https://*.hotjar.com https://*.hotjar.io https://www.clarity.ms/s/* wss://*.hotjar.com ${envVariables.vueAppApiBaseUrl} ${envVariables.vueAppRskNodeHost} ${envVariables.cspConfiguration} https://api.fireblocks.io/ https://api.coingecko.com/ https://*.clarity.ms https://www.clarity.ms/* https://rpc.walletconnect.com https://rpc.walletconnect.org https://relay.walletconnect.com https://relay.walletconnect.org wss://relay.walletconnect.com wss://relay.walletconnect.org https://pulse.walletconnect.com https://pulse.walletconnect.org https://api.web3modal.com https://api.web3modal.org https://public-node.testnet.rsk.co/ https://public-node.rsk.co https://mempool.space;
9393
object-src 'none';
9494
frame-src https://connect.trezor.io https://www.google.com/ https://verify.walletconnect.com https://verify.walletconnect.org https://secure.walletconnect.com https://secure.walletconnect.org;
9595
worker-src 'none';
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading

src/common/components/common/FileManager.vue

Lines changed: 0 additions & 56 deletions
This file was deleted.

src/common/components/exchange/BtcWalletDialog.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,11 @@ export default defineComponent({
249249
});
250250
return;
251251
}
252+
if (wallet === constants.WALLET_NAMES.FIREBLOCKS.long_name) {
253+
router.push({ name: 'NoWalletPegin' });
254+
emitClose();
255+
return;
256+
}
252257
addBitcoinWallet({
253258
bitcoinWallet: wallet,
254259
})

src/common/composables/useIndexdedDB.ts

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,18 @@ export function useIndexedDB() {
1919
}
2020

2121
async function saveFile(name: string, blob: Blob) {
22-
console.log('saving file', name);
2322
const db = await openDB();
2423
const tx = db.transaction(storeName, 'readwrite');
2524
const store = tx.objectStore(storeName);
26-
const key = await store.put({ name, content: blob });
27-
console.log('key', key);
25+
await store.put({ name, content: blob });
26+
return tx.commit();
27+
}
28+
29+
async function saveStringValue(name: string, value: string) {
30+
const db = await openDB();
31+
const tx = db.transaction(storeName, 'readwrite');
32+
const store = tx.objectStore(storeName);
33+
await store.put({ name, content: value, type: 'string' });
2834
return tx.commit();
2935
}
3036

@@ -44,5 +50,29 @@ export function useIndexedDB() {
4450
});
4551
}
4652

47-
return { saveFile, loadFile };
53+
async function loadStringValue(name: string): Promise<string | null> {
54+
const db = await openDB();
55+
const tx = db.transaction(storeName, 'readonly');
56+
const store = tx.objectStore(storeName);
57+
const request = store.get(name);
58+
59+
return new Promise((resolve) => {
60+
request.onsuccess = () => {
61+
const { result } = request;
62+
if (result?.type === 'string') {
63+
resolve(result.content);
64+
} else {
65+
resolve(null);
66+
}
67+
};
68+
request.onerror = () => resolve(null);
69+
});
70+
}
71+
72+
return {
73+
saveFile,
74+
loadFile,
75+
saveStringValue,
76+
loadStringValue,
77+
};
4878
}

src/common/router/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ const routes: Readonly<RouteRecordRaw[]> = [
116116
}
117117
},
118118
},
119+
{
120+
path: '/setupIBi',
121+
name: 'SetUpIBI',
122+
component: () => import(/* webpackChunkName: "IBIS" */ '../../pegin/views/SetUpIBI.vue'),
123+
},
124+
{
125+
path: '/noWalletPegin',
126+
name: 'NoWalletPegin',
127+
component: () => import(/* webpackChunkName: "no-wallet-pegin" */ '../../pegin/views/NoWalletPeginForm.vue'),
128+
},
119129
];
120130

121131
const history = createWebHistory(EnvironmentAccessorService.getEnvironmentVariables().baseUrl);
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/* eslint-disable class-methods-use-this */
2+
import { ApiService } from '@/common/services';
3+
import {
4+
ApiUsersResponse,
5+
BtcAccount, FireblocksLocalConfig,
6+
FireblocksResponse, FireblocksTransactionParams,
7+
VaultAccount, WalletAddress,
8+
} from '@/common/types';
9+
import axios from 'axios';
10+
import * as constants from '@/common/store/constants';
11+
import { buildJWT, generateExternalTxId } from '../utils';
12+
import { EnvironmentAccessorService } from './enviroment-accessor.service';
13+
14+
export default class FireblocksService {
15+
private config: FireblocksLocalConfig;
16+
17+
private apiUrl: string;
18+
19+
private vaults: VaultAccount[] = [];
20+
21+
private vaultId: number;
22+
23+
static btcAssetId = EnvironmentAccessorService
24+
.getEnvironmentVariables().vueAppCoin === constants.BTC_NETWORK_TESTNET ? 'BTC_TEST' : 'BTC';
25+
26+
constructor(config: FireblocksLocalConfig) {
27+
this.apiUrl = `${ApiService.baseURL}/fireblocks`;
28+
this.config = config;
29+
this.vaultId = config.vaultId;
30+
}
31+
32+
public setVaultId(vaultId: number) {
33+
this.vaultId = vaultId;
34+
}
35+
36+
// eslint-disable-next-line class-methods-use-this
37+
public async getAccountAddresses(): Promise<WalletAddress[]> {
38+
return new Promise((resolve, reject) => {
39+
const addresses: WalletAddress[] = [];
40+
this.getVaultAccounts().then((vaults) => {
41+
this.vaults = vaults;
42+
const vault = vaults.find((v) => v.id === this.vaultId);
43+
if (!vault) {
44+
reject(new Error('Vault not found'));
45+
}
46+
addresses.push({
47+
address: '',
48+
derivationPath: '',
49+
arrayPath: [],
50+
unused: false,
51+
publicKey: '',
52+
});
53+
resolve(addresses);
54+
}).catch((error) => {
55+
reject(error);
56+
});
57+
});
58+
}
59+
60+
name(): Record<'formal_name' | 'short_name' | 'long_name', string> {
61+
return constants.WALLET_NAMES.FIREBLOCKS;
62+
}
63+
64+
availableAccounts(): Array<BtcAccount> {
65+
return [BtcAccount.BITCOIN_NATIVE_SEGWIT_ADDRESS];
66+
}
67+
68+
// eslint-disable-next-line class-methods-use-this
69+
public async getVaultAccounts(): Promise<Array<VaultAccount>> {
70+
const uri = '/v1/vault/accounts_paged';
71+
const body = {
72+
limit: 200,
73+
orderBy: 'DESC',
74+
};
75+
const jwt = await buildJWT({
76+
pemKey: this.config.cert,
77+
apiKey: this.config.apiKey,
78+
uri,
79+
body: JSON.stringify(body),
80+
});
81+
const res = await axios.post(`${ApiService.baseURL}/fireblocks/generic-get`, {
82+
apiKey: this.config.apiKey,
83+
jwt,
84+
uri,
85+
bodyData: body,
86+
});
87+
return Promise.resolve(res.data.data.accounts);
88+
}
89+
90+
public async sendTransaction(params: FireblocksTransactionParams) {
91+
const uri = '/v1/transactions';
92+
const externalTxId = await generateExternalTxId(params);
93+
const body = JSON.stringify({ externalTxId, ...params });
94+
const jwt = await buildJWT({
95+
pemKey: this.config.cert,
96+
apiKey: this.config.apiKey,
97+
uri,
98+
body,
99+
});
100+
const res = await axios.post(`${this.apiUrl}/generic-post`, {
101+
apiKey: this.config.apiKey,
102+
jwt,
103+
uri,
104+
bodyData: { externalTxId, ...params },
105+
});
106+
return Promise.resolve(res.data.data);
107+
}
108+
109+
public async getApiUsers(): Promise<FireblocksResponse<ApiUsersResponse>> {
110+
return new Promise((resolve, reject) => {
111+
const uri = '/v1/management/api_users';
112+
const body = {
113+
limit: 200,
114+
orderBy: 'DESC',
115+
};
116+
buildJWT({
117+
pemKey: this.config.cert,
118+
apiKey: this.config.apiKey,
119+
uri,
120+
body: JSON.stringify(body),
121+
}).then((jwt) => axios.post(`${this.apiUrl}/generic-get`, {
122+
apiKey: this.config.apiKey,
123+
jwt,
124+
uri,
125+
bodyData: body,
126+
}))
127+
.then((res) => {
128+
resolve(res.data);
129+
})
130+
.catch(reject);
131+
});
132+
}
133+
}

src/common/store/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const WALLET_NAMES = {
66
XVERSE: { formal_name: 'Xverse', short_name: 'xverse', long_name: 'WALLET_XVERSE' },
77
ENKRYPT: { formal_name: 'Enkrypt', short_name: 'enkrypt', long_name: 'WALLET_ENKRYPT' },
88
REOWN: { formal_name: 'Reown', short_name: 'reown', long_name: 'WALLET_REOWN' },
9+
FIREBLOCKS: { formal_name: 'Fireblocks', short_name: 'fireblocks', long_name: 'WALLET_FIREBLOCKS' },
910
} as const;
1011

1112
export enum WalletTypes {

0 commit comments

Comments
 (0)