mirror of
https://github.com/aljazceru/ark.git
synced 2025-12-18 20:54:20 +01:00
[SDK] Fix rest client and wasm (#341)
* Fixes Co-authored-by: João Bordalo <bordalix@users.noreply.github.com> * Fixes to rest client * Fixes to wasm --------- Co-authored-by: João Bordalo <bordalix@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
a3deb2d596
commit
26bcbc8163
@@ -38,6 +38,7 @@ func NewClient(aspUrl string) (client.ASPClient, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// TODO: use twice the round interval.
|
||||||
reqTimeout := 15 * time.Second
|
reqTimeout := 15 * time.Second
|
||||||
treeCache := utils.NewCache[tree.CongestionTree]()
|
treeCache := utils.NewCache[tree.CongestionTree]()
|
||||||
|
|
||||||
@@ -223,25 +224,19 @@ func (a *restClient) SubmitSignedForfeitTxs(
|
|||||||
func (a *restClient) GetEventStream(
|
func (a *restClient) GetEventStream(
|
||||||
ctx context.Context, paymentID string,
|
ctx context.Context, paymentID string,
|
||||||
) (<-chan client.RoundEventChannel, func(), error) {
|
) (<-chan client.RoundEventChannel, func(), error) {
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, a.requestTimeout)
|
||||||
eventsCh := make(chan client.RoundEventChannel)
|
eventsCh := make(chan client.RoundEventChannel)
|
||||||
stopCh := make(chan struct{})
|
|
||||||
|
|
||||||
go func(payID string) {
|
go func(payID string, eventsCh chan client.RoundEventChannel) {
|
||||||
|
ticker := time.NewTicker(1 * time.Second)
|
||||||
defer close(eventsCh)
|
defer close(eventsCh)
|
||||||
defer close(stopCh)
|
defer ticker.Stop()
|
||||||
|
|
||||||
timeout := time.After(a.requestTimeout)
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-stopCh:
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
case <-timeout:
|
case <-ticker.C:
|
||||||
eventsCh <- client.RoundEventChannel{
|
|
||||||
Err: fmt.Errorf("timeout reached"),
|
|
||||||
}
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
event, err := a.Ping(ctx, payID)
|
event, err := a.Ping(ctx, payID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
eventsCh <- client.RoundEventChannel{
|
eventsCh <- client.RoundEventChannel{
|
||||||
@@ -255,17 +250,11 @@ func (a *restClient) GetEventStream(
|
|||||||
Event: event,
|
Event: event,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}(paymentID)
|
}(paymentID, eventsCh)
|
||||||
|
|
||||||
close := func() {
|
return eventsCh, cancel, nil
|
||||||
stopCh <- struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
return eventsCh, close, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *restClient) Ping(
|
func (a *restClient) Ping(
|
||||||
|
|||||||
@@ -2,20 +2,23 @@
|
|||||||
|
|
||||||
This example demonstrates how to compile ARK Go SDK to WebAssembly and use it in a web page.
|
This example demonstrates how to compile ARK Go SDK to WebAssembly and use it in a web page.
|
||||||
|
|
||||||
1. Create a Go file with the main package, check [main.go](main.go).
|
1. Copy `wasm_exec.js` to a new directory:
|
||||||
|
|
||||||
2. Copy `wasm_exec.js`:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp $(go env GOROOT)/misc/wasm/wasm_exec.js .
|
cp $(go env GOROOT)/misc/wasm/wasm_exec.js .
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Build the Go code to WebAssembly:
|
2. On the root directory of this repo, build the Go code to WebAssembly:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
GOOS=js GOARCH=wasm go build -o main.wasm main.go
|
make build-wasm
|
||||||
```
|
```
|
||||||
|
|
||||||
|
3. Move the wasm file to your directory
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mv <repo>/pkg/client-sdk/build/ark-sdk.wasm .
|
||||||
|
|
||||||
4. Load the WebAssembly module in a web page, check [index.html](index.html).
|
4. Load the WebAssembly module in a web page, check [index.html](index.html).
|
||||||
|
|
||||||
5. Serve the files:
|
5. Serve the files:
|
||||||
|
|||||||
@@ -44,8 +44,7 @@
|
|||||||
try {
|
try {
|
||||||
const addresses = await receive();
|
const addresses = await receive();
|
||||||
logMessage("Offchain address: " + addresses.offchainAddr);
|
logMessage("Offchain address: " + addresses.offchainAddr);
|
||||||
logMessage("Onchain address: " + addresses.onchainAddr);
|
logMessage("Boarding address: " + addresses.boardingAddr);
|
||||||
logMessage("If in regtest faucet onchain address: " + addresses.onchainAddr);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logMessage("Receive error: " + err.message);
|
logMessage("Receive error: " + err.message);
|
||||||
}
|
}
|
||||||
@@ -53,8 +52,10 @@
|
|||||||
|
|
||||||
async function getBalance() {
|
async function getBalance() {
|
||||||
const bal = await balance(false);
|
const bal = await balance(false);
|
||||||
logMessage("Onchain balance: " + bal.onchain_balance)
|
logMessage("Offchain balance: " + bal.offchainBalance)
|
||||||
logMessage("Offchain balance: " + bal.offchain_balance)
|
logMessage("Onchain balance: ")
|
||||||
|
logMessage(" Spendable: " + bal.onchainBalance.spendable)
|
||||||
|
logMessage(" Locked: " + bal.onchainBalance.locked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -88,6 +89,33 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function claimVtxos() {
|
||||||
|
const password = document.getElementById("c_password").value;
|
||||||
|
if (!password) {
|
||||||
|
logMessage("Claim error: password is required");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await unlock(password);
|
||||||
|
const txID = await claim();
|
||||||
|
logMessage("Claimed money with tx ID: " + txID);
|
||||||
|
} catch (err) {
|
||||||
|
logMessage("Claim error: " + err.message);
|
||||||
|
} finally {
|
||||||
|
await lock(password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function history() {
|
||||||
|
try {
|
||||||
|
const history = await getTransactionHistory();
|
||||||
|
logMessage("Tx history: " + history);
|
||||||
|
} catch (err) {
|
||||||
|
logMessage("Tx history error: " + err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function config() {
|
async function config() {
|
||||||
try {
|
try {
|
||||||
const aspUrl = await getAspUrl();
|
const aspUrl = await getAspUrl();
|
||||||
@@ -112,30 +140,6 @@
|
|||||||
logMessage("Config error: " + err.message);
|
logMessage("Config error: " + err.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function board() {
|
|
||||||
const amountStr = document.getElementById("amount").value;
|
|
||||||
const amount = parseInt(amountStr, 10);
|
|
||||||
const password = document.getElementById("o_password").value;
|
|
||||||
if (!password) {
|
|
||||||
logMessage("Onboard error: password is required");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
console.log("unlocking...");
|
|
||||||
await unlock(password);
|
|
||||||
console.log(amount, password);
|
|
||||||
console.log("onboarding...");
|
|
||||||
const txID = await onboard(amount);
|
|
||||||
logMessage("Onboarded with amount: " + amount + " and txID: " + txID + ", if in regtest mine a block");
|
|
||||||
} catch (err) {
|
|
||||||
logMessage("Onboard error: " + err.message);
|
|
||||||
} finally {
|
|
||||||
await lock(password);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -154,17 +158,19 @@
|
|||||||
<div>
|
<div>
|
||||||
<button onclick="getBalance()">Balance</button>
|
<button onclick="getBalance()">Balance</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<button onclick="board()">Onboard</button>
|
|
||||||
<input type="text" id="amount" placeholder="Amount">
|
|
||||||
<input type="password" id="o_password" placeholder="password">
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<button onclick="send()">Send</button>
|
<button onclick="send()">Send</button>
|
||||||
<input type="text" id="sendAddress" placeholder="Offchain Address">
|
<input type="text" id="sendAddress" placeholder="Offchain Address">
|
||||||
<input type="text" id="amountToSend" placeholder="Amount">
|
<input type="text" id="amountToSend" placeholder="Amount">
|
||||||
<input type="password" id="s_password" placeholder="password">
|
<input type="password" id="s_password" placeholder="password">
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<button onclick="claimVtxos()">Claim</button>
|
||||||
|
<input type="password" id="c_password" placeholder="password">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button onclick="history()">History</button>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button onclick="config()">Config</button>
|
<button onclick="config()">Config</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -30,8 +30,10 @@ func init() {
|
|||||||
js.Global().Set("receive", ReceiveWrapper())
|
js.Global().Set("receive", ReceiveWrapper())
|
||||||
js.Global().Set("sendOnChain", SendOnChainWrapper())
|
js.Global().Set("sendOnChain", SendOnChainWrapper())
|
||||||
js.Global().Set("sendOffChain", SendOffChainWrapper())
|
js.Global().Set("sendOffChain", SendOffChainWrapper())
|
||||||
|
js.Global().Set("claim", ClaimWrapper())
|
||||||
js.Global().Set("unilateralRedeem", UnilateralRedeemWrapper())
|
js.Global().Set("unilateralRedeem", UnilateralRedeemWrapper())
|
||||||
js.Global().Set("collaborativeRedeem", CollaborativeRedeemWrapper())
|
js.Global().Set("collaborativeRedeem", CollaborativeRedeemWrapper())
|
||||||
|
js.Global().Set("getTransactionHistory", GetTransactionHistoryWrapper())
|
||||||
js.Global().Set("log", LogWrapper())
|
js.Global().Set("log", LogWrapper())
|
||||||
|
|
||||||
js.Global().Set("getAspUrl", GetAspUrlWrapper())
|
js.Global().Set("getAspUrl", GetAspUrlWrapper())
|
||||||
|
|||||||
@@ -6,9 +6,12 @@ package browser
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
|
"time"
|
||||||
|
|
||||||
arksdk "github.com/ark-network/ark/pkg/client-sdk"
|
arksdk "github.com/ark-network/ark/pkg/client-sdk"
|
||||||
"github.com/ark-network/ark/pkg/client-sdk/wallet"
|
"github.com/ark-network/ark/pkg/client-sdk/wallet"
|
||||||
@@ -119,21 +122,25 @@ func BalanceWrapper() js.Func {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
onchainBalance int
|
onchainSpendableBalance int
|
||||||
|
onchainLockedBalance int
|
||||||
offchainBalance int
|
offchainBalance int
|
||||||
)
|
)
|
||||||
|
|
||||||
if resp == nil {
|
if resp != nil {
|
||||||
onchainBalance = 0
|
onchainSpendableBalance = int(resp.OnchainBalance.SpendableAmount)
|
||||||
offchainBalance = 0
|
for _, b := range resp.OnchainBalance.LockedAmount {
|
||||||
} else {
|
onchainLockedBalance += int(b.Amount)
|
||||||
onchainBalance = int(resp.OnchainBalance.SpendableAmount)
|
}
|
||||||
offchainBalance = int(resp.OffchainBalance.Total)
|
offchainBalance = int(resp.OffchainBalance.Total)
|
||||||
}
|
}
|
||||||
|
|
||||||
result := map[string]interface{}{
|
result := map[string]interface{}{
|
||||||
"onchain_balance": onchainBalance,
|
"onchainBalance": map[string]interface{}{
|
||||||
"offchain_balance": offchainBalance,
|
"spendable": onchainSpendableBalance,
|
||||||
|
"locked": onchainLockedBalance,
|
||||||
|
},
|
||||||
|
"offchainBalance": offchainBalance,
|
||||||
}
|
}
|
||||||
|
|
||||||
return js.ValueOf(result), nil
|
return js.ValueOf(result), nil
|
||||||
@@ -204,6 +211,21 @@ func SendOffChainWrapper() js.Func {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ClaimWrapper() js.Func {
|
||||||
|
return JSPromise(func(args []js.Value) (interface{}, error) {
|
||||||
|
if len(args) != 0 {
|
||||||
|
return nil, errors.New("invalid number of args")
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := arkSdkClient.Claim(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return js.ValueOf(resp), nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func UnilateralRedeemWrapper() js.Func {
|
func UnilateralRedeemWrapper() js.Func {
|
||||||
return JSPromise(func(args []js.Value) (interface{}, error) {
|
return JSPromise(func(args []js.Value) (interface{}, error) {
|
||||||
return nil, arkSdkClient.UnilateralRedeem(context.Background())
|
return nil, arkSdkClient.UnilateralRedeem(context.Background())
|
||||||
@@ -229,6 +251,32 @@ func CollaborativeRedeemWrapper() js.Func {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetTransactionHistoryWrapper() js.Func {
|
||||||
|
return JSPromise(func(args []js.Value) (interface{}, error) {
|
||||||
|
history, err := arkSdkClient.GetTransactionHistory(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rawHistory := make([]map[string]interface{}, 0)
|
||||||
|
for _, record := range history {
|
||||||
|
rawHistory = append(rawHistory, map[string]interface{}{
|
||||||
|
"boardingTxid": record.BoardingTxid,
|
||||||
|
"roundTxid": record.RoundTxid,
|
||||||
|
"redeemTxid": record.RedeemTxid,
|
||||||
|
"amount": strconv.Itoa(int(record.Amount)),
|
||||||
|
"type": record.Type,
|
||||||
|
"isPending": record.IsPending,
|
||||||
|
"createdAt": record.CreatedAt.Format(time.RFC3339),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
result, err := json.MarshalIndent(rawHistory, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return js.ValueOf(string(result)), nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func GetAspUrlWrapper() js.Func {
|
func GetAspUrlWrapper() js.Func {
|
||||||
return js.FuncOf(func(this js.Value, p []js.Value) interface{} {
|
return js.FuncOf(func(this js.Value, p []js.Value) interface{} {
|
||||||
data, _ := arkSdkClient.GetConfigData(context.Background())
|
data, _ := arkSdkClient.GetConfigData(context.Background())
|
||||||
|
|||||||
@@ -421,7 +421,6 @@ func (s *covenantService) startRound() {
|
|||||||
round := domain.NewRound(dustAmount)
|
round := domain.NewRound(dustAmount)
|
||||||
//nolint:all
|
//nolint:all
|
||||||
round.StartRegistration()
|
round.StartRegistration()
|
||||||
s.lastEvent = nil
|
|
||||||
s.currentRound = round
|
s.currentRound = round
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|||||||
@@ -712,7 +712,6 @@ func (s *covenantlessService) startRound() {
|
|||||||
round := domain.NewRound(dustAmount)
|
round := domain.NewRound(dustAmount)
|
||||||
//nolint:all
|
//nolint:all
|
||||||
round.StartRegistration()
|
round.StartRegistration()
|
||||||
s.lastEvent = nil
|
|
||||||
s.currentRound = round
|
s.currentRound = round
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|||||||
Reference in New Issue
Block a user