Skip to content
This repository was archived by the owner on May 16, 2024. It is now read-only.

Commit adb5175

Browse files
Feat central registry (#18)
* wip * Fix issues * add output type filter * wip * wip * update electron * update node * replace remote module * wip * wip * clean up electron.js * wip * Fix bug * wip * integrate asset info fetching * clean up comments * disable logging * Feat update lib (#17) * wip * Fix issues * add output type filter * wip * wip * update electron * update node * replace remote module * wip * wip * clean up electron.js * Fix bug * clean up comments * disable logging * fix apiRegistryClient unhandled exception * wip Co-authored-by: Begoña Alvarez <[email protected]>
1 parent dca785d commit adb5175

File tree

13 files changed

+275
-12
lines changed

13 files changed

+275
-12
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## v0.6.2
4+
5+
Add Asset Registry support
6+
37
## v0.6.0
48

59
Add PoW for requesting funds

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "pollen-wallet",
33
"description": "IOTA Pollen Wallet",
4-
"version": "0.6.0",
4+
"version": "0.6.2",
55
"author": "Martyn Janes <[email protected]>",
66
"repository": {
77
"type": "git",

src/app/App.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ class App extends Component<AppProps, AppState> {
8787
})
8888
} />
8989
)}
90+
{this.state.displayMode === "wallet" &&
91+
(!this.state.wallet || (this.state.wallet && !this.state.wallet.seed)) &&
92+
this.state.settings?.apiRegistryEndpoint === "http://asset-registry.tokenizedassetsdemo.iota.cafe" && (
93+
<div className="card margin-t-s">
94+
<div className="card--header">
95+
<h2>Asset Registry Connection</h2>
96+
</div>
97+
</div>
98+
)}
9099
{this.state.displayMode === "wallet" &&
91100
(!this.state.wallet || (this.state.wallet && !this.state.wallet.seed)) &&
92101
this.state.settings?.apiEndpoint === "http://127.0.0.1:8080" && (

src/app/components/Settings.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class Settings extends Component<SettingsProps, SettingsState> {
3535
const settings = await this._settingsService.get();
3636
this.setState({
3737
settings,
38+
apiRegistryEndpoint: settings.apiRegistryEndpoint,
3839
apiEndpoint: settings.apiEndpoint,
3940
user: settings.user,
4041
password: settings.password,
@@ -56,6 +57,17 @@ class Settings extends Component<SettingsProps, SettingsState> {
5657
<h2>General</h2>
5758
</div>
5859
<div className="card--content">
60+
{/* <div className="card--label">
61+
API Asset Registry Endpoint
62+
</div>
63+
<div className="card--value">
64+
<input
65+
className="fill"
66+
type="text"
67+
value={this.state.apiRegistryEndpoint}
68+
onChange={e => this.setState({ apiRegistryEndpoint: e.target.value })}
69+
/>
70+
</div> */}
5971
<div className="card--label">
6072
API Endpoint
6173
</div>
@@ -139,7 +151,13 @@ class Settings extends Component<SettingsProps, SettingsState> {
139151
newEndpoint = newEndpoint.substr(0, newEndpoint.length - 1);
140152
}
141153

154+
let newRegistryEndpoint = this.state.apiRegistryEndpoint ?? "";
155+
if (newRegistryEndpoint.endsWith("/")) {
156+
newRegistryEndpoint = newRegistryEndpoint.substr(0, newRegistryEndpoint.length - 1);
157+
}
158+
142159
const newSettings: ISettings = {
160+
apiRegistryEndpoint: newRegistryEndpoint,
143161
apiEndpoint: newEndpoint,
144162
user: this.state.user ?? "",
145163
password: this.state.password ?? "",

src/app/components/SettingsState.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export interface SettingsState {
1111
*/
1212
settings?: ISettings;
1313

14+
/**
15+
* The api Central Reigstry endpoint.
16+
*/
17+
apiRegistryEndpoint?: string;
18+
1419
/**
1520
* The api endpoint.
1621
*/

src/iota/api/apiRegistryClient.ts

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import fetch from "node-fetch";
2+
import { IAssetRequest } from "./models/IAssetRequest";
3+
import { IAssetResponse } from "./models/IAssetResponse";
4+
import { IResponse } from "./models/IResponse";
5+
6+
/**
7+
* Class to handle API communications.
8+
*/
9+
export class ApiRegistryClient {
10+
/**
11+
* The end point of the api.
12+
*/
13+
private readonly _endpoint: string;
14+
15+
/**
16+
* The user of the api.
17+
*/
18+
private readonly _user?: string;
19+
20+
/**
21+
* The password of the api.
22+
*/
23+
private readonly _password?: string;
24+
25+
/**
26+
* Create a new instance of ApiClient.
27+
* @param endPoint The endpoint for the API.
28+
* @param user The user for the API.
29+
* @param password The password for the API.
30+
*/
31+
constructor(endPoint: string, user?: string, password?: string) {
32+
this._endpoint = endPoint;
33+
this._user = user;
34+
this._password = password;
35+
}
36+
37+
/**
38+
* Fetch Asset info.
39+
* @returns The response from the request.
40+
*/
41+
public async fetchAsset(assetID: string): Promise<IAssetResponse> {
42+
return this.sendRequest<null, IAssetResponse>(
43+
"get", "registries/test/assets/"+assetID);
44+
}
45+
46+
/**
47+
* Reigester Asset info.
48+
* @returns The response from the request.
49+
*/
50+
public async registerAsset(request: IAssetRequest): Promise<IAssetResponse> {
51+
return this.sendRequest<IAssetRequest, IAssetResponse>(
52+
"post", "registries/test/assets", request);
53+
}
54+
55+
/**
56+
* Send a request and handle errors.
57+
* @param verb The HTTP verb to make the request.
58+
* @param path The path to send the request to.
59+
* @param request The request to send.
60+
* @returns The response from the request.
61+
*/
62+
private async sendRequest<T, U extends IResponse>(
63+
verb: "put" | "post" | "get" | "delete",
64+
path: string,
65+
request?: T | undefined): Promise<U> {
66+
let response: U;
67+
68+
try {
69+
const headers: { [id: string]: string } = {};
70+
headers["Content-Type"] = "application/json";
71+
72+
if (this._user && this._password) {
73+
headers.Authorization = `Basic ${btoa(`${this._user}:${this._password}`)}`;
74+
}
75+
76+
let fetchResponse;
77+
78+
if (verb === "get") {
79+
fetchResponse = await fetch(
80+
`${this._endpoint}/${path}`,
81+
{
82+
method: "get",
83+
headers
84+
}
85+
);
86+
} else if (verb === "post") {
87+
fetchResponse = await fetch(
88+
`${this._endpoint}/${path}`,
89+
{
90+
method: "post",
91+
headers,
92+
body: JSON.stringify(request)
93+
}
94+
);
95+
} else if (verb === "put") {
96+
fetchResponse = await fetch(
97+
`${this._endpoint}/${path}`,
98+
{
99+
method: "put",
100+
headers,
101+
body: JSON.stringify(request)
102+
}
103+
);
104+
} else if (verb === "delete") {
105+
fetchResponse = await fetch(
106+
`${this._endpoint}/${path}`,
107+
{
108+
method: "delete",
109+
headers
110+
}
111+
);
112+
}
113+
114+
if (!fetchResponse) {
115+
throw new Error("No data was returned from the API");
116+
} else {
117+
try {
118+
response = await fetchResponse.json();
119+
} catch (err) {
120+
const text = await fetchResponse.text();
121+
throw new Error(err.message + " --- " + text);
122+
}
123+
if (!fetchResponse.ok) {
124+
if (response.error) {
125+
throw new Error(response.error);
126+
} else {
127+
const isComError = fetchResponse.status >= 500;
128+
let msg = fetchResponse.statusText;
129+
130+
if (msg === "Network Error") {
131+
msg = "There is a problem communicating with the network";
132+
}
133+
134+
if (!msg.endsWith(".")) {
135+
msg += ".";
136+
}
137+
138+
if (isComError) {
139+
msg += "\n\nPlease try again later.";
140+
}
141+
142+
throw new Error(msg);
143+
}
144+
}
145+
}
146+
} catch (err) {
147+
throw new Error(`The application is not able to complete the request, due to the following error:\n\n${err.message}`);
148+
}
149+
150+
return response;
151+
}
152+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface IAssetRequest {
2+
ID: string;
3+
name: string;
4+
symbol: string;
5+
supply: number;
6+
transactionID: string;
7+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { IResponse } from "./IResponse";
2+
3+
export interface IAssetResponse extends IResponse {
4+
ID: string;
5+
name: string;
6+
symbol: string;
7+
supply: number;
8+
transactionID: string;
9+
}

src/iota/transaction.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export class Transaction {
2626
public static mintIndex(outputs: { [address: string]: {color: string; value: bigint }[] }): number {
2727
let mintOutput = "";
2828
let mintAddress = "";
29-
let mintOutputIndex = 0;
29+
let mintOutputIndex = -1;
3030

3131
const bufferOutputs: Buffer[] = [];
3232
for (const address in outputs) {

src/models/ISendFundsResponse.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface ISendFundsResponse {
2+
transactionID: string;
3+
4+
assetID?: string;
5+
}

0 commit comments

Comments
 (0)