perlin-network / lens Goto Github PK
View Code? Open in Web Editor NEWThe official network explorer for Wavelet.
The official network explorer for Wavelet.
Upon opening up Lens, we should prompt users for their private key which may be specified in a text input box as a hex string.
The private key will be passed to the Perlin
instance, and all API calls/session instantiation will thereafter be done under a given private key.
In the Himitsu branch, the account api is returning
{
"public_key":"e919a3626df31b6114ec79567726e9a31c600a5d192e871de1b862412ae8e4c0",
"balance":9999999383999825315,
"gas_balance":0,"stake":0,"reward":0,"is_contract":false
}
but the resulting balance displayed is 9,999,999,383.999826 PERLs
Most probably a rounding error somewhere, but definitely problematic.
Lens does not allow to logout if you enter an incorrect API URL by mistake until the request has failed. A minor issue but can be annoying.
Steps to reproduce:
1 - Login to Lens using an incorrect API URL such as test.perlin.net
2 - Try to logout. It should fail
3 - wait for a few moments until you see the red connection error.
4 - Try again and now you can logout successfully.
As of Wavelet v0.2.0, the gas cost of a transaction has increased to be proportional to its size instead of the single fixed value of 2 (in units of kens) in versions prior to v0.2.0
Currently, a transfer operation takes 15 kens and it might be sufficient to use that value instead of 2 for the gas cost of a transfer, but smart contract calls will need to be handled in a more complex way.
There have been some dependency problems appearing around wavelet-dev-server.
Since it's harder to manually fix each dependency it's better to create a new CRA project and copy current codebase into it.
Currently, on the Himitsu branch, when you open lens for the first time it results in a blank blue screen.
Console has a couple of "Max call stack exceeded" errors:
2.45465cb8.chunk.js:1 [mobx] Encountered an uncaught exception that was thrown by a reaction or observer component, in: 'Reaction[Reaction@8]' RangeError: Maximum call stack size exceeded
at L (2.45465cb8.chunk.js:1)
at t.get [as notification] (2.45465cb8.chunk.js:1)
at t.get [as notification] (2.45465cb8.chunk.js:1)
at t.get [as notification] (2.45465cb8.chunk.js:1)
at t.get [as notification] (2.45465cb8.chunk.js:1)
at t.get [as notification] (2.45465cb8.chunk.js:1)
at t.get [as notification] (2.45465cb8.chunk.js:1)
at t.get [as notification] (2.45465cb8.chunk.js:1)
at t.get [as notification] (2.45465cb8.chunk.js:1)
at t.get [as notification] (2.45465cb8.chunk.js:1)
A.reportExceptionInDerivation @ 2.45465cb8.chunk.js:1
A.track @ 2.45465cb8.chunk.js:1
v @ 2.45465cb8.chunk.js:1
(anonymous) @ 2.45465cb8.chunk.js:1
A.runReaction @ 2.45465cb8.chunk.js:1
...
(anonymous) @ main.e33f414b.chunk.js:1
Show 6 more frames
2.45465cb8.chunk.js:1 RangeError: Maximum call stack size exceeded
at L (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
vo @ 2.45465cb8.chunk.js:1
So.t.callback @ 2.45465cb8.chunk.js:1
xi @ 2.45465cb8.chunk.js:1
_i @ 2.45465cb8.chunk.js:1
Da @ 2.45465cb8.chunk.js:1
e.unstable_runWithPriority @ 2.45465cb8.chunk.js:1
...
(anonymous) @ main.e33f414b.chunk.js:1
2.45465cb8.chunk.js:1 Uncaught RangeError: Maximum call stack size exceeded
at L (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
at t.get [as api] (2.45465cb8.chunk.js:1)
Say you have 3 Perl and you send yourself 3 Perls. It shows Recipients balance as 6 but it is actually only 2,999999985 Perl.
Unpon loading a new contract, remove the initial parameter input.
Here is a function, given a WebAssembly smart contract as a file input, that will list out all exported contract functions of said contract.
private onLoadContract = async (event: any) => {
if (this.store.file === null) {
return;
}
const reader = new FileReader();
const bytes = await new Promise((resolve, reject) => {
reader.onerror = () => {
reader.abort();
reject(new DOMException("Failed to parse contract file."))
}
reader.onload = () => {
resolve(reader.result as any);
}
reader.readAsArrayBuffer(this.store.file as Blob);
});
// @ts-ignore
const contract = await WebAssembly.instantiate(bytes, {
env: {
_payload_len: () => 0, _payload: () => 0, _provide_result: () => 0, _send_transaction: () => 0
}
});
const contractPrefix = "_contract_";
let exportedFunctions = _.filter(Object.keys(contract.instance.exports), exp => exp.startsWith(contractPrefix));
exportedFunctions = _.map(exportedFunctions, exp => exp.substr(contractPrefix.length));
console.log(exportedFunctions);
}
Smart contract functions have parameters and return payloads as byte arrays. They are executed in the context of the transactions sender.
A UI component is needed to specify a list of parameters, and to parse the return payloads of a contracts execution. The return payload of a transaction is collected by locally executing the smart contract function on the client-side.
An option exists to also directly send the smart contract function call transaction as-is to the ledger via /transaction/send.
Example parameters and result for a function that sends some money to a recipient:
Function name: _contract_transfer
Function params: [(String) "recipient wallet address here", (unsigned int 64) 100]
Function return results: [(boolean which is an unsigned 8-bit int) true]
All data types are laid out to be little-endian.
The smart contract function transfer
is defined in Rust as:
fn transfer(&mut self, params: &mut Parameters) -> Option<Payload> {
let recipient: Vec<u8> = params.read();
let amount: u64 = params.read();
let mut result = Payload::new();
let sender_balance = match self.balances.get(¶ms.sender) {
Some(balance) => *balance,
None => 0
};
// Throw an error if the sender does not have enough balance.
if sender_balance < amount {
result.write(&false);
return Some(result);
}
let recipient_balance = match self.balances.get(&recipient) {
Some(balance) => *balance,
None => 0
};
// Modify balances.
self.balances.insert(params.sender.clone(), sender_balance - amount);
self.balances.insert(recipient, recipient_balance + amount);
// Return `true` to the sender that the transfer was successful.
result.write(&true);
return Some(result);
}
Strings are laid out to end with a termination character \0
:
impl Writeable for String {
fn write_to(&self, buffer: &mut Vec<u8>) {
for x in self.chars() {
x.write_to(buffer);
}
'\0'.write_to(buffer);
}
}
Byte arrays (Vec) are prefixed with their length:
impl<T: Writeable> Writeable for Vec<T> {
fn write_to(&self, buffer: &mut Vec<u8>) {
self.len().write_to(buffer);
for x in self {
x.write_to(buffer);
}
}
}
Booleans are 8-bit unsigned integers that are either 0 or 1.
Balances should automatically update after a transactions is made
Right now the API endpoint for Wavelet is hard-coded in.
We should provide a prompt to input and connect to different Wavelet HTTP API endpoints, and also save all endpoints down to browser local storage.
If there's a contract ID in the URL, the page will load and highlight that Contract.
Searching for a contract ID will move the user to the Developer page with the contract highlighted.
If an account has 1 PERL, and you send exactly 1 PERL, you will get a "successfully sent TX" message, but the TX will actually fail & deduct the TX fee, leaving the user with 0.999999998 PERLs
Since wavelet-client can now accept strings for numeric parameters, and there's another similar purpose library (bignumber.js) we should remove JSBI to simplify the code.
Originally opened as perlin-network/wavelet#252
When generating private keys for use with Wavelet the blake2b(blake2b(publicKey))
needs to begin with C1
bits of 0s
See:
Currently without and with the Testnet C1 set to 1
, about 50% of private keys generated on Lens can't be used for nodes on the Wavelet testnet
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.