Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 0 additions & 34 deletions .github/workflows/check-contract-build.yml

This file was deleted.

36 changes: 0 additions & 36 deletions .github/workflows/rs-tests.yml

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ data/
logs/
.idea/
epoch-proxy-server
contracts/
22 changes: 11 additions & 11 deletions frontend/src/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ interface UserDetails {
interface CryptoPaymentState {
isServiceAvailable: boolean;
isPaused: boolean;
requestsPerEGLD: number;
creditsPerEGLD: number;
walletURL: string;
explorerURL: string;
contractAddress: string;
minimumBalance: number;

paymentId: number | null;
depositAddress: string | null;
numberOfRequests: number;
credits: number;

isLoading: boolean;
error: string | null;
Expand Down Expand Up @@ -111,14 +111,14 @@ export const Dashboard = () => {
const [cryptoState, setCryptoState] = useState<CryptoPaymentState>({
isServiceAvailable: false,
isPaused: false,
requestsPerEGLD: 10000,
creditsPerEGLD: 10000,
walletURL: 'https://devnet-wallet.multiversx.com',
explorerURL: 'https://devnet-explorer.multiversx.com',
contractAddress: 'erd1qqqqqqqqqqqqqpgqc6u0p4kfkr5ekcrae86m6knx46gr36khrqqqhf96zw',
minimumBalance: 0,
paymentId: null,
depositAddress: null,
numberOfRequests: 0,
credits: 0,
isLoading: false,
error: null
});
Expand All @@ -141,7 +141,7 @@ export const Dashboard = () => {
const newState = {
isServiceAvailable: config.isAvailable,
isPaused: config.isPaused,
requestsPerEGLD: config.requestsPerEGLD,
creditsPerEGLD: config.creditsPerEGLD,
walletURL: ensureProtocol(config.walletURL),
explorerURL: ensureProtocol(config.explorerURL),
contractAddress: config.contractAddress,
Expand All @@ -164,7 +164,7 @@ export const Dashboard = () => {
...prev,
paymentId: accountRes.data.paymentId,
depositAddress: accountRes.data.address,
numberOfRequests: accountRes.data.numberOfRequests
credits: accountRes.data.credits
}));
}
} catch (accErr: any) {
Expand All @@ -177,7 +177,7 @@ export const Dashboard = () => {
...prev,
paymentId: null,
depositAddress: null,
numberOfRequests: 0
credits: 0
}));
}
}
Expand All @@ -191,7 +191,7 @@ export const Dashboard = () => {
isServiceAvailable: false,
isPaused: false, // Ensure paused state is cleared if service is down
isLoading: false,
requestsPerEGLD: 0, // Reset rate
creditsPerEGLD: 0, // Reset rate
error: err.response?.data?.error || "Crypto service unavailable"
}));
}
Expand All @@ -217,7 +217,7 @@ export const Dashboard = () => {
...prev,
paymentId: accountRes.data.paymentId,
depositAddress: accountRes.data.address,
numberOfRequests: accountRes.data.numberOfRequests,
credits: accountRes.data.credits,
isLoading: false
}));
// Also refresh the main user data to ensure all views are in sync
Expand Down Expand Up @@ -636,7 +636,7 @@ export const Dashboard = () => {
</p>
<div className="flex flex-wrap gap-2 mb-6">
<span className="bg-white/5 px-2 py-1 rounded text-xs text-slate-300">
Rate: {cryptoState.requestsPerEGLD ? cryptoState.requestsPerEGLD.toLocaleString() : '-'} req / 1 EGLD
Rate: {cryptoState.creditsPerEGLD ? cryptoState.creditsPerEGLD.toLocaleString() : '-'} credits / 1 EGLD
</span>
<span className="bg-white/5 px-2 py-1 rounded text-xs text-slate-300">Activation: under 3 minutes</span>
</div>
Expand Down Expand Up @@ -727,7 +727,7 @@ export const Dashboard = () => {
</div>
<div>
<label className="text-xs text-slate-500 block mb-1">Current Rate</label>
<div className="text-slate-200">{cryptoState.requestsPerEGLD ? cryptoState.requestsPerEGLD.toLocaleString() : '-'} req/EGLD</div>
<div className="text-slate-200">{cryptoState.creditsPerEGLD ? cryptoState.creditsPerEGLD.toLocaleString() : '-'} credits/EGLD</div>
</div>
<div className="col-span-2 mt-1">
<div className="text-[10px] text-amber-500/80 font-medium flex items-center gap-1.5 uppercase tracking-wide">
Expand Down
4 changes: 2 additions & 2 deletions integrationTests/go/cryptoPayment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/stretchr/testify/require"
)

const functionGetRequests = "getRequests"
const functionGetCredits = "getCredits"

var log = logger.GetOrCreate("integrationTests")

Expand Down Expand Up @@ -293,7 +293,7 @@ func checkCredits(ctx context.Context, service *framework.CryptoPaymentService,
result := service.ChainSimulator.ExecuteVMQuery(
ctx,
service.ContractAddress,
functionGetRequests,
functionGetCredits,
[]string{
hex.EncodeToString(big.NewInt(int64(id)).Bytes()),
},
Expand Down
2 changes: 1 addition & 1 deletion integrationTests/go/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func TestCreateFreeUserAndCreateKeyAndTestRequestsAreThrottledThenSwitchToPremiu
// Generate a block to ensure any pending txs (from balanceProcessor) are processed
cryptoPaymentService.ChainSimulator.GenerateBlocks(ctx, 1)

reqs := session.GetNumberOfRequests()
reqs := session.GetCredits()
return reqs >= 50
}, 2*time.Minute, 1*time.Second)
log.Info("Done ✓")
Expand Down
2 changes: 1 addition & 1 deletion integrationTests/go/framework/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const CallGasLimit = 3000000
func GetContractPath(contractName string) string {
currentDir := traverse("integrationTests")

return filepath.Join(currentDir, "requests-contract", "output", contractName, contractName+".wasm")
return filepath.Join(currentDir, "contracts", contractName, contractName+".wasm")
}

// GetProxyRootPath returns the absolute path to the proxy service root path
Expand Down
8 changes: 4 additions & 4 deletions integrationTests/go/framework/cryptoPaymentService.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,22 @@ func NewCryptoPaymentService(tb testing.TB) *CryptoPaymentService {
}

// Setup prepares the environment
func (crs *CryptoPaymentService) Setup(ctx context.Context, numRequestsPerEGLD int64) {
func (crs *CryptoPaymentService) Setup(ctx context.Context, creditsPerEGLD int64) {
log.Info("minting tokens to the users")
crs.ChainSimulator.FundWallets(ctx, crs.Keys.WalletsToFundOnMultiversX())

log.Info("deploying contract")
address, _, txOnNetwork := crs.ChainSimulator.DeploySC(
ctx,
GetContractPath("requests"),
GetContractPath("credits"),
crs.Keys.OwnerKeys.MvxSk,
deployGasLimit,
[]string{
hex.EncodeToString(big.NewInt(numRequestsPerEGLD).Bytes()),
hex.EncodeToString(big.NewInt(creditsPerEGLD).Bytes()),
},
)

log.Info("deployed the requests contract", "address", address.Bech32(), "txHash", txOnNetwork.Hash)
log.Info("deployed the credits contract", "address", address.Bech32(), "txHash", txOnNetwork.Hash)
crs.ContractAddress = address
}

Expand Down
130 changes: 130 additions & 0 deletions integrationTests/go/framework/downloader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package framework

import (
"archive/zip"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"strings"
)

const (
contractCreditsVersionTag = "v1.0.0"
contractCreditsURL = "https://github.com/iulianpascalau/credits-contract-rs/releases/download/" + contractCreditsVersionTag + "/credits-contract.zip"
)

func init() {
if !IsChainSimulatorIsRunning() {
return
}
err := ensureContractCredits()
if err != nil {
fmt.Printf("WARNING: Failed to ensure credits contract: %v\n", err)
// We deliberately panic here because if we can't get the contract, tests will fail anyway
panic(err)
}
}

func ensureContractCredits() error {
root := traverse("integrationTests")
extractTarget := filepath.Join(root, "contracts")
contractDir := filepath.Join(extractTarget, "credits")
contractPath := filepath.Join(contractDir, "credits.wasm")

if _, err := os.Stat(contractPath); err == nil {
// Contract exists. We could check versioning (e.g. hash) but for now existence matches intent.
return nil
}

fmt.Printf("Downloading credits contract from %s...\n", contractCreditsURL)
resp, err := http.Get(contractCreditsURL)
if err != nil {
return fmt.Errorf("failed to download contract: %w", err)
}
defer func() {
_ = resp.Body.Close()
}()

if resp.StatusCode != http.StatusOK {
return fmt.Errorf("bad status: %s", resp.Status)
}

// Create temp file
tmpFile, err := os.CreateTemp("", "credits-contract-*.zip")
if err != nil {
return fmt.Errorf("failed to create temp file: %w", err)
}
defer func() {
_ = os.Remove(tmpFile.Name())
}()

_, err = io.Copy(tmpFile, resp.Body)
if err != nil {
return fmt.Errorf("failed to write temp file: %w", err)
}
_ = tmpFile.Close()

// Unzip
r, err := zip.OpenReader(tmpFile.Name())
if err != nil {
return fmt.Errorf("failed to open zip reader: %w", err)
}
defer func() {
_ = r.Close()
}()

err = os.MkdirAll(extractTarget, 0755)

if err != nil {
return fmt.Errorf("failed to create target dir: %w", err)
}

for _, f := range r.File {
fpath := filepath.Join(extractTarget, f.Name)

// ZipSlip check
if !strings.HasPrefix(fpath, filepath.Clean(extractTarget)+string(os.PathSeparator)) {
return fmt.Errorf("illegal file path: %s", fpath)
}

if f.FileInfo().IsDir() {
err = os.MkdirAll(fpath, os.ModePerm)
if err != nil {
return err
}
continue
}

err = os.MkdirAll(filepath.Dir(fpath), os.ModePerm)
if err != nil {
return err
}

var outFile *os.File
outFile, err = os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return err
}

var rc io.ReadCloser
rc, err = f.Open()
if err != nil {
_ = outFile.Close()
return err
}

_, err = io.Copy(outFile, rc)

_ = outFile.Close()
_ = rc.Close()

if err != nil {
return err
}
}

fmt.Println("Successfully downloaded and extracted credits contract.")
return nil
}
9 changes: 5 additions & 4 deletions integrationTests/go/framework/testSession.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ func (session *testSession) GetDepositAddress() string {
return session.depositAddress
}

func (session *testSession) GetNumberOfRequests() int {
// GetCredits returns the number of credits
func (session *testSession) GetCredits() int {
req, _ := http.NewRequest(http.MethodGet, session.baseAddress+api.EndpointApiCryptoPaymentAccount, nil)
req.Header.Set("Authorization", "Bearer "+session.jwtToken)
client := &http.Client{}
Expand All @@ -197,11 +198,11 @@ func (session *testSession) GetNumberOfRequests() int {
var acc map[string]interface{}
_ = json.NewDecoder(resp.Body).Decode(&acc)

// Check numberOfRequests. Should be around 50 (0.5 EGLD * 100 requests/EGLD)
reqs, ok := acc["numberOfRequests"].(float64)
// Check credits
credits, ok := acc["credits"].(float64)
if !ok {
return -1
}

return int(reqs)
return int(credits)
}
Loading