Skip to content

Commit

Permalink
modal UI overhaul and added insufficient balance checks for trial acc…
Browse files Browse the repository at this point in the history
…ounts
  • Loading branch information
BenKurrek committed Apr 17, 2023
1 parent d8478ee commit a6864b4
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 19 deletions.
6 changes: 3 additions & 3 deletions docs-advanced-tutorials/trial-accounts/create-trial-drop.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const {
createTrialAccountDrop
} = keypom

const funderAccountId = 'md1.testnet';
const funderAccountId = 'benjiman.testnet';
const NETWORK_ID = 'testnet';
async function createTrialAccount() {
// Initiate connection to the NEAR blockchain.
Expand Down Expand Up @@ -56,12 +56,12 @@ async function createTrialAccount() {
numKeys: 1,
contractBytes: [...readFileSync(wasmDirectory)],
// How much $NEAR should be made available to the trial account when it's created?
startingBalanceNEAR: 2.5,
startingBalanceNEAR: 0.05,
callableContracts,
callableMethods,
maxAttachableNEARPerContract,
// Once the trial account has spent this much $NEAR, the trial will be over.
trialEndFloorNEAR: 1.25
trialEndFloorNEAR: .01
})

const guestBookInstance = "http://localhost:1234"
Expand Down
Binary file modified docs-advanced-tutorials/trial-accounts/ext-wasm/trial-accounts.wasm
Binary file not shown.
10 changes: 8 additions & 2 deletions docs-advanced-tutorials/trial-accounts/guest-book/keypom-data.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ export {
trialCallMethod,
canExitTrial
} from "./lib/trial-accounts/trial-active";
export {
wrapTxnParamsForTrial
} from "./lib/trial-accounts/utils";
export {
addKeys,
deleteKeys
Expand Down
14 changes: 12 additions & 2 deletions src/lib/selector/core/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,21 @@ export class KeypomWallet implements InstantLinkWalletBehaviour {
console.log(`e: ${JSON.stringify(e)}`)
switch (e) {
case TRIAL_ERRORS.EXIT_EXPECTED: {
this.modal.show({id: MODAL_TYPE_IDS.TRIAL_OVER});
this.modal.show({
id: MODAL_TYPE_IDS.TRIAL_OVER,
meta: {
accountId: this.trialAccountId!,
secretKey: this.trialSecretKey!
}
});
break;
}
case TRIAL_ERRORS.INVALID_ACTION: {
this.modal.show({id: MODAL_TYPE_IDS.ERROR});
this.modal.show({id: MODAL_TYPE_IDS.ACTION_ERROR});
break;
}
case TRIAL_ERRORS.INSUFFICIENT_BALANCE: {
this.modal.show({id: MODAL_TYPE_IDS.INSUFFICIENT_BALANCE});
break;
}
default: {
Expand Down
27 changes: 27 additions & 0 deletions src/lib/selector/modal/src/lib/components/InsufficientBalance.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from "react";
import { MODAL_DEFAULTS } from "../modal.types";
import { MainBody } from "./MainBody";

interface InsufficientBalanceProps {
hide: () => void;
}

export const InsufficientBalance: React.FC<InsufficientBalanceProps> = ({
hide
}) => {
return (
<div className="nws-modal" style={{ width: "70%", height: "27%" }}>
<div className="modal-right" style={{ width: "100%" }}>
<MainBody
title={MODAL_DEFAULTS.insufficientBalance.title}
body={MODAL_DEFAULTS.insufficientBalance.body}
headerOne={null}
headerTwo={null}
onCloseModal={() =>
hide()
}
/>
</div>
</div>
);
};
4 changes: 2 additions & 2 deletions src/lib/selector/modal/src/lib/components/InvalidActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export const InvalidActions: React.FC<InvalidActionsProps> = ({
<div className="nws-modal" style={{ width: "70%", height: "27%" }}>
<div className="modal-right" style={{ width: "100%" }}>
<MainBody
title={MODAL_DEFAULTS.error.title}
body={MODAL_DEFAULTS.error.body}
title={MODAL_DEFAULTS.invalidAction.title}
body={MODAL_DEFAULTS.invalidAction.body}
headerOne={null}
headerTwo={null}
onCloseModal={() =>
Expand Down
9 changes: 6 additions & 3 deletions src/lib/selector/modal/src/lib/handleModalType.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from "react";
import { ClaimTrial } from "./components/ClaimTrial";
import { InsufficientBalance } from "./components/InsufficientBalance";
import { InvalidActions } from "./components/InvalidActions";
import { TrialOver } from "./components/TrialOver";
import { ModalOptions, ModalType, MODAL_TYPE_IDS } from "./modal.types";
Expand All @@ -11,8 +12,8 @@ export const renderModalType = (modalType: ModalType, options: ModalOptions, hid
<TrialOver
modulesTitle={options.modulesTitle}
modules={options.modules}
accountId={options.accountId}
secretKey={options.secretKey}
accountId={modalType.meta.accountId}
secretKey={modalType.meta.secretKey}
mainTitle={options.mainTitle}
mainBody={options.mainBody}
headerOne={options.headerOne}
Expand All @@ -21,8 +22,10 @@ export const renderModalType = (modalType: ModalType, options: ModalOptions, hid
hide={hide}
/>
)
case MODAL_TYPE_IDS.ERROR:
case MODAL_TYPE_IDS.ACTION_ERROR:
return <InvalidActions hide={hide} />
case MODAL_TYPE_IDS.INSUFFICIENT_BALANCE:
return <InsufficientBalance hide={hide} />
case MODAL_TYPE_IDS.CLAIM_TRIAL:
return <ClaimTrial hide={hide} secretKey={modalType.meta.secretKey} redirectUrlBase={modalType.meta.redirectUrlBase} delimiter={modalType.meta.delimiter}/>
default: return null;
Expand Down
9 changes: 7 additions & 2 deletions src/lib/selector/modal/src/lib/modal.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ export interface ModalType {
export const MODAL_TYPE_IDS = {
CLAIM_TRIAL: "claim-trial",
TRIAL_OVER: "trial-over",
ERROR: "action-error"
ACTION_ERROR: "action-error",
INSUFFICIENT_BALANCE: "insufficient-balance"
}
export const MODAL_DEFAULTS = {
claimTrial: {
Expand All @@ -74,8 +75,12 @@ export const MODAL_DEFAULTS = {
modulesTitle: "Choose a Wallet",
}
},
error: {
invalidAction: {
title: "Invalid Action",
body: "Your trial does not allow you to perform this action. For more information, please contact the site administrator."
},
insufficientBalance: {
title: "Insufficient Balance",
body: "Your account does not have enough balance for the action you are trying to perform. Please try again with a different action. For more information, please contact the site administrator."
}
}
16 changes: 13 additions & 3 deletions src/lib/trial-accounts/trial-active.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { FinalExecutionOutcome } from "@near-wallet-selector/core";
import { KeyPair } from "near-api-js";
import { getEnv } from "../keypom";
import { createTransactions } from "../keypom-utils";
import { estimateTrialGas, generateExecuteArgs, TRIAL_ERRORS, validateDesiredMethods } from "./utils";
import { estimateTrialGas, generateExecuteArgs, hasEnoughBalance, TRIAL_ERRORS, validateDesiredMethods } from "./utils";


/**
Expand Down Expand Up @@ -133,7 +133,7 @@ export const trialSignAndSendTxns = async ({
throw TRIAL_ERRORS.EXIT_EXPECTED;
}

const {methodDataToValidate, executeArgs} = await generateExecuteArgs({desiredTxns: txns});
const {methodDataToValidate, executeArgs, totalAttachedYocto, totalGasForTxns} = await generateExecuteArgs({desiredTxns: txns});

const isValidTxn = await validateDesiredMethods({methodData: methodDataToValidate, trialAccountId});
console.log('isValidTxn: ', isValidTxn)
Expand All @@ -142,6 +142,11 @@ export const trialSignAndSendTxns = async ({
throw TRIAL_ERRORS.INVALID_ACTION;
}

const hasBal = await hasEnoughBalance({trialAccountId, totalAttachedYocto, totalGasForTxns});
if (hasBal == false) {
throw TRIAL_ERRORS.INSUFFICIENT_BALANCE;
}

const trialKeyPair = KeyPair.fromString(trialAccountSecretKey);
const pubKey = trialKeyPair.getPublicKey();
await keyStore!.setKey(networkId!, trialAccountId, trialKeyPair)
Expand Down Expand Up @@ -278,7 +283,7 @@ export const trialCallMethod = async ({
}];
console.log(`txns: ${JSON.stringify(txns)}`)

const {methodDataToValidate, executeArgs} = await generateExecuteArgs({desiredTxns: txns});
const {methodDataToValidate, executeArgs, totalAttachedYocto, totalGasForTxns} = await generateExecuteArgs({desiredTxns: txns});

const isValidTxn = await validateDesiredMethods({methodData: methodDataToValidate, trialAccountId});
console.log('isValidTxn: ', isValidTxn)
Expand All @@ -287,6 +292,11 @@ export const trialCallMethod = async ({
throw TRIAL_ERRORS.INVALID_ACTION;
}

const hasBal = await hasEnoughBalance({trialAccountId, totalAttachedYocto, totalGasForTxns});
if (hasBal == false) {
throw TRIAL_ERRORS.INSUFFICIENT_BALANCE;
}

const trialKeyPair = KeyPair.fromString(trialAccountSecretKey);
const pubKey = trialKeyPair.getPublicKey();
await keyStore!.setKey(networkId!, trialAccountId, trialKeyPair)
Expand Down
36 changes: 34 additions & 2 deletions src/lib/trial-accounts/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ const PARAM_STOP = '|kS|'

export const TRIAL_ERRORS = {
EXIT_EXPECTED: 'exit',
INVALID_ACTION: 'invalid_action'
INVALID_ACTION: 'invalid_action',
INSUFFICIENT_BALANCE: 'insufficient_balance'
}

export const validateDesiredMethods = async ({
Expand Down Expand Up @@ -116,6 +117,8 @@ export const generateExecuteArgs = ({ desiredTxns }: {
}[];
}) => {
const methodDataToValidate: any = [];
let totalGasBN = new BN(0);
let totalDepositsBN = new BN(0);
const executeArgs: any = {
transactions: []
}
Expand All @@ -133,6 +136,8 @@ export const generateExecuteArgs = ({ desiredTxns }: {
methodName: action.params.methodName,
deposit: action.params.deposit
})
totalGasBN = totalGasBN.add(new BN(action.params.gas))
totalDepositsBN = totalDepositsBN.add(new BN(action.params.deposit))

const newAction: any = {}
console.log('newAction 1: ', newAction)
Expand All @@ -145,6 +150,8 @@ export const generateExecuteArgs = ({ desiredTxns }: {
executeArgs.transactions.push(newTx)
})
return {
totalAttachedYocto: totalDepositsBN.toString(),
totalGasForTxns: totalGasBN.toString(),
executeArgs,
methodDataToValidate
}
Expand Down Expand Up @@ -224,4 +231,29 @@ export const isUnclaimedTrialDrop = async ({keypomContractId, secretKey}) => {
}

return false;
}
}

export const hasEnoughBalance = async ({
trialAccountId,
totalGasForTxns,
totalAttachedYocto
}: {
trialAccountId: string;
totalGasForTxns: string;
totalAttachedYocto: string;
}) => {
const {near} = getEnv();

const trialAccountObj = new Account(near!.connection, trialAccountId);
const accountState = await trialAccountObj.state();

const storageCostPerByte = new BN('10000000000000000000');
const totalStorage = new BN(accountState.storage_usage).mul(storageCostPerByte);
let availAmount = new BN(accountState.amount).sub(totalStorage);

const yoctoPerGas = 100000000;
let gasCost = new BN(totalGasForTxns).mul(new BN(yoctoPerGas));
let totalCost = gasCost.add(new BN(totalAttachedYocto));

return availAmount.gte(totalCost);
}

0 comments on commit a6864b4

Please sign in to comment.