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

Commit

Permalink
Feat central registry (#18)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
capossele and begonaalvarezd authored May 21, 2021
1 parent dca785d commit adb5175
Show file tree
Hide file tree
Showing 13 changed files with 275 additions and 12 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v0.6.2

Add Asset Registry support

## v0.6.0

Add PoW for requesting funds
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "pollen-wallet",
"description": "IOTA Pollen Wallet",
"version": "0.6.0",
"version": "0.6.2",
"author": "Martyn Janes <[email protected]>",
"repository": {
"type": "git",
Expand Down
9 changes: 9 additions & 0 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ class App extends Component<AppProps, AppState> {
})
} />
)}
{this.state.displayMode === "wallet" &&
(!this.state.wallet || (this.state.wallet && !this.state.wallet.seed)) &&
this.state.settings?.apiRegistryEndpoint === "http://asset-registry.tokenizedassetsdemo.iota.cafe" && (
<div className="card margin-t-s">
<div className="card--header">
<h2>Asset Registry Connection</h2>
</div>
</div>
)}
{this.state.displayMode === "wallet" &&
(!this.state.wallet || (this.state.wallet && !this.state.wallet.seed)) &&
this.state.settings?.apiEndpoint === "http://127.0.0.1:8080" && (
Expand Down
18 changes: 18 additions & 0 deletions src/app/components/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Settings extends Component<SettingsProps, SettingsState> {
const settings = await this._settingsService.get();
this.setState({
settings,
apiRegistryEndpoint: settings.apiRegistryEndpoint,
apiEndpoint: settings.apiEndpoint,
user: settings.user,
password: settings.password,
Expand All @@ -56,6 +57,17 @@ class Settings extends Component<SettingsProps, SettingsState> {
<h2>General</h2>
</div>
<div className="card--content">
{/* <div className="card--label">
API Asset Registry Endpoint
</div>
<div className="card--value">
<input
className="fill"
type="text"
value={this.state.apiRegistryEndpoint}
onChange={e => this.setState({ apiRegistryEndpoint: e.target.value })}
/>
</div> */}
<div className="card--label">
API Endpoint
</div>
Expand Down Expand Up @@ -139,7 +151,13 @@ class Settings extends Component<SettingsProps, SettingsState> {
newEndpoint = newEndpoint.substr(0, newEndpoint.length - 1);
}

let newRegistryEndpoint = this.state.apiRegistryEndpoint ?? "";
if (newRegistryEndpoint.endsWith("/")) {
newRegistryEndpoint = newRegistryEndpoint.substr(0, newRegistryEndpoint.length - 1);
}

const newSettings: ISettings = {
apiRegistryEndpoint: newRegistryEndpoint,
apiEndpoint: newEndpoint,
user: this.state.user ?? "",
password: this.state.password ?? "",
Expand Down
5 changes: 5 additions & 0 deletions src/app/components/SettingsState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export interface SettingsState {
*/
settings?: ISettings;

/**
* The api Central Reigstry endpoint.
*/
apiRegistryEndpoint?: string;

/**
* The api endpoint.
*/
Expand Down
152 changes: 152 additions & 0 deletions src/iota/api/apiRegistryClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import fetch from "node-fetch";
import { IAssetRequest } from "./models/IAssetRequest";
import { IAssetResponse } from "./models/IAssetResponse";
import { IResponse } from "./models/IResponse";

/**
* Class to handle API communications.
*/
export class ApiRegistryClient {
/**
* The end point of the api.
*/
private readonly _endpoint: string;

/**
* The user of the api.
*/
private readonly _user?: string;

/**
* The password of the api.
*/
private readonly _password?: string;

/**
* Create a new instance of ApiClient.
* @param endPoint The endpoint for the API.
* @param user The user for the API.
* @param password The password for the API.
*/
constructor(endPoint: string, user?: string, password?: string) {
this._endpoint = endPoint;
this._user = user;
this._password = password;
}

/**
* Fetch Asset info.
* @returns The response from the request.
*/
public async fetchAsset(assetID: string): Promise<IAssetResponse> {
return this.sendRequest<null, IAssetResponse>(
"get", "registries/test/assets/"+assetID);
}

/**
* Reigester Asset info.
* @returns The response from the request.
*/
public async registerAsset(request: IAssetRequest): Promise<IAssetResponse> {
return this.sendRequest<IAssetRequest, IAssetResponse>(
"post", "registries/test/assets", request);
}

/**
* Send a request and handle errors.
* @param verb The HTTP verb to make the request.
* @param path The path to send the request to.
* @param request The request to send.
* @returns The response from the request.
*/
private async sendRequest<T, U extends IResponse>(
verb: "put" | "post" | "get" | "delete",
path: string,
request?: T | undefined): Promise<U> {
let response: U;

try {
const headers: { [id: string]: string } = {};
headers["Content-Type"] = "application/json";

if (this._user && this._password) {
headers.Authorization = `Basic ${btoa(`${this._user}:${this._password}`)}`;
}

let fetchResponse;

if (verb === "get") {
fetchResponse = await fetch(
`${this._endpoint}/${path}`,
{
method: "get",
headers
}
);
} else if (verb === "post") {
fetchResponse = await fetch(
`${this._endpoint}/${path}`,
{
method: "post",
headers,
body: JSON.stringify(request)
}
);
} else if (verb === "put") {
fetchResponse = await fetch(
`${this._endpoint}/${path}`,
{
method: "put",
headers,
body: JSON.stringify(request)
}
);
} else if (verb === "delete") {
fetchResponse = await fetch(
`${this._endpoint}/${path}`,
{
method: "delete",
headers
}
);
}

if (!fetchResponse) {
throw new Error("No data was returned from the API");
} else {
try {
response = await fetchResponse.json();
} catch (err) {
const text = await fetchResponse.text();
throw new Error(err.message + " --- " + text);
}
if (!fetchResponse.ok) {
if (response.error) {
throw new Error(response.error);
} else {
const isComError = fetchResponse.status >= 500;
let msg = fetchResponse.statusText;

if (msg === "Network Error") {
msg = "There is a problem communicating with the network";
}

if (!msg.endsWith(".")) {
msg += ".";
}

if (isComError) {
msg += "\n\nPlease try again later.";
}

throw new Error(msg);
}
}
}
} catch (err) {
throw new Error(`The application is not able to complete the request, due to the following error:\n\n${err.message}`);
}

return response;
}
}
7 changes: 7 additions & 0 deletions src/iota/api/models/IAssetRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface IAssetRequest {
ID: string;
name: string;
symbol: string;
supply: number;
transactionID: string;
}
9 changes: 9 additions & 0 deletions src/iota/api/models/IAssetResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { IResponse } from "./IResponse";

export interface IAssetResponse extends IResponse {
ID: string;
name: string;
symbol: string;
supply: number;
transactionID: string;
}
2 changes: 1 addition & 1 deletion src/iota/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class Transaction {
public static mintIndex(outputs: { [address: string]: {color: string; value: bigint }[] }): number {
let mintOutput = "";
let mintAddress = "";
let mintOutputIndex = 0;
let mintOutputIndex = -1;

const bufferOutputs: Buffer[] = [];
for (const address in outputs) {
Expand Down
5 changes: 5 additions & 0 deletions src/models/ISendFundsResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface ISendFundsResponse {
transactionID: string;

assetID?: string;
}
5 changes: 5 additions & 0 deletions src/models/ISettings.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export interface ISettings {
/**
* API Central Registry Endpoint.
*/
apiRegistryEndpoint: string;

/**
* API Endpoint.
*/
Expand Down
4 changes: 4 additions & 0 deletions src/services/settingsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export class SettingsService implements ISettingsService {

if (!this._settings) {
this._settings = {
apiRegistryEndpoint: "http://asset-registry.tokenizedassetsdemo.iota.cafe",
apiEndpoint: "http://127.0.0.1:8080",
user: "",
password: "",
Expand All @@ -43,6 +44,9 @@ export class SettingsService implements ISettingsService {
};
}

// always override local settings
this._settings.apiRegistryEndpoint = "http://asset-registry.tokenizedassetsdemo.iota.cafe";

return this._settings;
}

Expand Down
Loading

0 comments on commit adb5175

Please sign in to comment.