@bugbytes/hapi-connect
Version:
Lightweight HashConnect Browser Side Client Library
163 lines • 6.63 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createParingString = exports.HashConnectClient = void 0;
const simple_crypto_js_1 = __importDefault(require("simple-crypto-js"));
const base64 = __importStar(require("@protobufjs/base64"));
const relay_1 = require("./relay");
const util_1 = require("./util");
class HashConnectClient {
relay;
topics;
pending;
constructor(relay = new relay_1.Relay()) {
this.topics = new Map();
this.pending = [];
this.relay = relay;
this.relay.connected.on(() => {
for (const topic of this.topics.keys()) {
this.relay.send(JSON.stringify({ action: "sub", topic: topic }));
}
});
this.relay.received.on((payload) => {
if (payload) {
const { timestamp, type, data, topic } = JSON.parse(JSON.parse(payload));
const secret = this.topics.get(topic);
if (secret) {
const decryptedData = new simple_crypto_js_1.default(secret).decrypt(data);
const message = { timestamp, type, data: decryptedData, topic };
for (let i = 0; i < this.pending.length; i++) {
if (this.pending[i](message)) {
this.pending.splice(i, 1);
break;
}
}
// Remove this section of code when we're sure we don't need it.
// Not sure if its necessary, and sometimes causes an ACK storm.
// this.send(topic, 'Acknowledge', {
// result: handeled,
// topic: topic,
// msg_id: (decryptedData as any).id
// });
}
}
});
}
connect(topic, secret) {
this.topics.set(topic, secret);
if (this.relay.isOpen) {
this.relay.send(JSON.stringify({ action: "sub", topic: topic }));
}
}
sendTransaction(topic, transaction, accountToSign, returnTransaction = false) {
const id = (0, util_1.createRandomId)();
this.send(topic, "Transaction", {
id,
topic,
byteArray: base64.encode(transaction, 0, transaction.length),
metadata: { accountToSign, returnTransaction },
});
return new Promise((resolve) => {
const handler = (message) => {
// Note Potential Bug: We have no correlation ID in the protocol
// to discern if this is really the response paired with the
// request we sent to the remote wallet. So we assume the first
// handler in the list with the topic will get the response.
if (message.type === "TransactionResponse" && message.topic === topic) {
setTimeout(() => resolve(message.data), 0);
return true;
}
return false;
};
this.pending.push(handler);
});
}
requestAdditionalAccounts(topic, network, multiAccount) {
const id = (0, util_1.createRandomId)();
this.send(topic, "AdditionalAccountRequest", {
id,
topic,
network,
multiAccount,
});
return new Promise((resolve) => {
const handler = (message) => {
// Note Potential Bug: We have no correlation ID in the protocol
// to discern if this is really the response paired with the
// request we sent to the remote wallet. So we assume the first
// handler in the list with the topic will get the response.
if (message.type === "AdditionalAccountResponse" &&
message.topic === topic) {
setTimeout(() => resolve(message.data), 0);
return true;
}
return false;
};
this.pending.push(handler);
});
}
waitForPairing(topic) {
return new Promise((resolve) => {
const handler = (message) => {
if (message.type === "ApprovePairing" && message.topic === topic) {
setTimeout(() => resolve(message.data), 0);
return true;
}
return false;
};
this.pending.push(handler);
});
}
send(topic, type, payload) {
const timestamp = Date.now();
const data = new simple_crypto_js_1.default(this.topics.get(topic)).encrypt(JSON.stringify(payload));
this.relay.send(JSON.stringify({
action: "pub",
payload: JSON.stringify(JSON.stringify({ timestamp, type, data, topic })),
topic,
}));
}
}
exports.HashConnectClient = HashConnectClient;
function createParingString(topic, secret, name, description, network) {
const data = new TextEncoder().encode(JSON.stringify({
metadata: {
name,
description,
url: "",
icon: "",
publicKey: secret,
},
topic,
network,
multiAccount: false,
}));
return base64.encode(data, 0, data.length);
}
exports.createParingString = createParingString;
//# sourceMappingURL=client.js.map