Skip to content

Commit

Permalink
wallet1
Browse files Browse the repository at this point in the history
  • Loading branch information
snadrus committed Nov 5, 2024
1 parent 34abdc9 commit a8685d6
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 1 deletion.
5 changes: 5 additions & 0 deletions harmony/harmonydb/sql/20241105-walletnames.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE wallet_names (
id SERIAL PRIMARY KEY,
wallet_id VARCHAR NOT NULL,
name VARCHAR(60) NOT NULL
);
108 changes: 108 additions & 0 deletions web/api/webrpc/wallet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package webrpc

import (
"context"
"fmt"
"strings"
"sync"

"github.com/filecoin-project/curio/deps/config"
"github.com/filecoin-project/curio/harmony/harmonydb"
"github.com/filecoin-project/go-address"
"golang.org/x/exp/maps"
)

var walletOnce sync.Once

func (a *WebRPC) WalletName(ctx context.Context, id string) (string, error) {
walletOnce.Do(func() {
populateWalletFriendlyNames(a.deps.Cfg.Addresses, a.deps.DB)
})
walletFriendlyNamesLock.Lock()
defer walletFriendlyNamesLock.Unlock()
return walletFriendlyNames[id], nil
}

func (a *WebRPC) WalletNameChange(ctx context.Context, id string, newName string) error {
_, err := a.deps.DB.Exec(ctx, `UDPATE wallet_names SET name = $1 WHERE id = $2`, newName, id)
if err != nil {
log.Errorf("failed to set wallet name for %s: %s", id, err)
return err
}
walletFriendlyNamesLock.Lock()
defer walletFriendlyNamesLock.Unlock()
walletFriendlyNames[id] = newName
return nil
}

var walletFriendlyNames = map[string]string{}
var walletFriendlyNamesLock sync.Mutex

func populateWalletFriendlyNames(addrGrps []config.CurioAddresses, db *harmonydb.DB) {
type nx struct {
purposes map[string]bool
miner map[string]bool
}
ex := map[string]*nx{}
all_purposes := []string{"PC_Ctrl", "Cmt_Ctrl", "Term_Ctrl"}
allMiners := map[string]bool{}
for _, addrList := range addrGrps {
n := map[string][]string{
"PC_Ctrl": addrList.PreCommitControl,
"Cmt_Ctrl": addrList.CommitControl,
"Term_Ctrl": addrList.TerminateControl,
}
for name, addrs := range n {
for i, addr := range addrs {
a, err := address.NewFromString(addr)
if err != nil {
continue
}
allMiners[a.String()] = true

if len(addrs) > 1 {
name = fmt.Sprintf("%s%d", name, i)
}
if res, ok := ex[a.String()]; ok {
res.purposes[name] = true
for _, miner := range addrList.MinerAddresses {
res.miner[miner] = true
}
} else {
var t = map[string]bool{}
for _, miner := range addrList.MinerAddresses {
t[miner] = true
}
ex[a.String()] = &nx{purposes: map[string]bool{name: true}, miner: t}
}
}
}
}
for addr, nx := range ex {
purpose := ""
miner := ""
if len(nx.purposes) != len(all_purposes) { // impossible to be 0
purpose = strings.Join(maps.Keys(nx.purposes), ",")
}
if len(nx.miner) != len(allMiners) { // impoossible to be 0
miner = "_" + strings.Join(maps.Keys(nx.miner), ",")
}
if purpose == "" && miner == "" {
purpose = "all"
}
walletFriendlyNames[addr] = purpose + miner + "Wallet"
}

var idNames []struct {
ID string
Name string
}
err := db.Select(context.Background(), &idNames, `SELECT wallet_id as ID, name FROM wallet_names`)
if err != nil {
log.Errorf("failed to get wallet names: %s", err)
return
}
for _, idName := range idNames {
walletFriendlyNames[idName.ID] = idName.Name
}
}
3 changes: 2 additions & 1 deletion web/static/actor-summary.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { LitElement, html, css } from 'https://cdn.jsdelivr.net/gh/lit/dist@3/all/lit-all.min.js';
import RPCCall from '/lib/jsonrpc.mjs';
import '/lib/cu-wallet.mjs';

class Expirations extends LitElement {
static properties = {
Expand Down Expand Up @@ -249,7 +250,7 @@ class ActorSummary extends LitElement {
<tbody>
${this.data.map(entry => html`
<tr>
<td>${entry.Address}</td>
<td><cu-wallet .wallet_id="${entry.Address}" /></td>
<td>
${entry.CLayers.map(layer => html`<span>${layer} </span>`)}
</td>
Expand Down
63 changes: 63 additions & 0 deletions web/static/lib/cu-wallet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { LitElement, html } from 'https://cdn.jsdelivr.net/gh/lit/dist@3/all/lit-all.min.js';
import RPCCall from '/lib/jsonrpc.mjs';

class CuWallet extends LitElement {
static get properties() {
return {
wallet_id: { type: String }
};
}

constructor() {
super();
this.wallet_id = '';
}

updated(changedProperties) {
if (changedProperties.has('wallet_id') && this.wallet_id) {
this.handleIdUpdate();
}
}

async handleIdUpdate() {
this.isProcessing = true;
try {
this.name = await RPCCall('WalletName', [this.wallet_id]);
} catch (error) {
console.error('Error during WalletName operation:', error);
} finally {
this.isProcessing = false;
}
this.requestUpdate();
}

nice_id() {
if (!this.wallet_id) return 'Not Set';
if (this.name != '') return this.name;
return this.wallet_id.substring(0, 6) + '...' + this.wallet_id.substring(this.wallet_id.length - 6);
}
static styles = css`
@keyframes spinner {
to {transform: rotate(360deg);}
}
.spinner:before {
content: url('/favicon.svg');
display: inline-block;
animation: spinner 1s linear infinite;
height: 12px;
}
`;

render() {
return html`
<div class="wallet">
${this.isProcessing ? html`<span class="spinner"></span>` : ''}
<a href="/pages/wallet/?id=${this.wallet_id}">📛</a>
<span>${this.nice_id()}</span>
<a @click=${() => navigator.clipboard.writeText(this.wallet_id)}>📋</a>
</div>
`;
}
}

customElements.define('cu-wallet', CuWallet);
19 changes: 19 additions & 0 deletions web/static/pages/wallet/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Wallet</title>
<script type="module" src="./wallet.mjs"></script>
<script type="module" src="/ux/curio-ux.mjs"></script>
<body style="visibility:hidden" data-bs-theme="dark">
<curio-ux>
<wallet-component></wallet-component>
</curio-ux>
<script>
const walletComponent = document.querySelector('wallet-component');
walletComponent.wallet_id = new URLSearchParams(window.location.search).get('id');
document.body.appendChild(walletComponent);
</script>
</body>
</html>
81 changes: 81 additions & 0 deletions web/static/pages/wallet/wallet.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { LitElement, html } from 'https://cdn.jsdelivr.net/gh/lit/dist@3/all/lit-all.min.js';
import RPCCall from '/lib/jsonrpc.mjs';

class CuWallet extends LitElement {
static get properties() {
return {
wallet_id: { type: String }
};
}

constructor() {
super();
this.wallet_id = '';
}

updated(changedProperties) {
if (changedProperties.has('wallet_id') && this.wallet_id) {
this.handleIdUpdate();
}
}

async handleIdUpdate() {
this.isProcessing = true;
try {
let res = await RPCCall('WalletName', [this.wallet_id]); // TODO API call
this.name = res.name;
this.requestUpdate();
} catch (error) {
console.error('Error during WalletName operation:', error);
} finally {
this.isProcessing = false;
}
}

nice_id() {
if (!this.wallet_id) return 'Not Set';
if (this.name != '') return this.name;
return this.wallet_id.substring(0, 6) + '...' + this.wallet_id.substring(this.wallet_id.length - 6);
}
async handleNameChange(new_nice_id) {
this.isProcessing = true;
this.name = new_nice_id;
this.requestUpdate();
try {
await RPCCall('WalletNameChange', [this.wallet_id, new_nice_id]); // TODO API call
} catch (error) {
console.error('Error during WalletName operation:', error);
} finally {
this.isProcessing = false;
}
this.requestUpdate();
}
static styles = css`
@keyframes spinner {
to {transform: rotate(360deg);}
}
.spinner:before {
content: url('/favicon.svg');
display: inline-block;
animation: spinner 1s linear infinite;
height: 12px;
}
`;

render() {
return html`
<div class="wallet">
${this.isProcessing ? html`<span class="spinner"></span>` : ''}
Full ID: <span>${this.wallet_id}</span><br>
<form @submit=${(e) => {
e.preventDefault()
this.handleNameChange(e.target.walletName.value)
}}>
<input type="text" name="walletName" .value=${this.nice_id()}>
<button type="submit">Change Name</button>
</form>
</div> `;
}
}

customElements.define('wallet-component', CuWallet);

0 comments on commit a8685d6

Please sign in to comment.