557 support hodl invoices (#620)
* build htlc functions * adding color override to dropdown icons * adding invoice generation for hodl invoices * building logic to check if any hodl invoice was paid * fixing confirm toast message * adding claim htlc to expanded details page * adding translations * fixing eslint * updating spark web package
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -29,6 +29,7 @@ const DropdownMenu = ({
|
||||
customFunction,
|
||||
translateLabelText = true,
|
||||
globalContainerStyles = {},
|
||||
customVericalArrowsColor = null,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const dropdownRef = useRef(null);
|
||||
@@ -120,7 +121,11 @@ const DropdownMenu = ({
|
||||
},
|
||||
]}
|
||||
>
|
||||
<ThemeIcon size={20} iconName={'ChevronsUpDown'} />
|
||||
<ThemeIcon
|
||||
colorOverride={customVericalArrowsColor}
|
||||
size={20}
|
||||
iconName={'ChevronsUpDown'}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -4,10 +4,11 @@ import {
|
||||
SATSPERBITCOIN,
|
||||
} from '../../constants';
|
||||
import { breezLiquidReceivePaymentWrapper } from '../breezLiquid';
|
||||
|
||||
import { randomBytes } from 'react-native-quick-crypto';
|
||||
import customUUID from '../customUUID';
|
||||
import { crashlyticsLogReport } from '../crashlyticsLogs';
|
||||
import { sparkReceivePaymentWrapper } from '../spark/payments';
|
||||
import { encriptMessage } from '../messaging/encodingAndDecodingMessages';
|
||||
import { getRootstockAddress } from '../boltz/rootstock/submarineSwap';
|
||||
import { formatBip21Address } from '../spark/handleBip21SparkAddress';
|
||||
import { getLocalStorageItem, setLocalStorageItem } from '../localStorage';
|
||||
@@ -106,48 +107,85 @@ export async function initializeAddressProcess(wolletInfo) {
|
||||
((wolletInfo.poolInfoRef.lpFeeBps + 100 + 10000) / 10000),
|
||||
);
|
||||
|
||||
const [response, swapResponse] = await Promise.all([
|
||||
sparkReceivePaymentWrapper({
|
||||
if (wolletInfo.isHoldInvoice && wolletInfo.endReceiveType === 'BTC') {
|
||||
// Generate random preimage and derive payment hash
|
||||
const preimage = randomBytes(32);
|
||||
const paymentHash = sha256Hash(preimage).toString('hex');
|
||||
const preimageHex = Buffer.from(preimage).toString('hex');
|
||||
|
||||
// Encrypt preimage to self using user's nostr key pair
|
||||
const encryptedPreimage = encriptMessage(
|
||||
wolletInfo.contactsPrivateKey,
|
||||
wolletInfo.contactsPublicKey,
|
||||
preimageHex,
|
||||
);
|
||||
|
||||
const response = await sparkReceivePaymentWrapper({
|
||||
paymentType: 'lightning',
|
||||
amountSats:
|
||||
wolletInfo.endReceiveType === 'USD'
|
||||
? swapAmountWithFee
|
||||
: uniqueAmount,
|
||||
amountSats: uniqueAmount,
|
||||
memo: wolletInfo.description,
|
||||
mnemoinc: wolletInfo.currentWalletMnemoinc,
|
||||
sendWebViewRequest,
|
||||
performSwaptoUSD: wolletInfo.endReceiveType === 'USD',
|
||||
expirySeconds: wolletInfo.endReceiveType === 'USD' ? 600 : undefined,
|
||||
includeSparkAddress: wolletInfo.endReceiveType !== 'USD',
|
||||
}),
|
||||
wolletInfo.endReceiveType === 'USD'
|
||||
? simulateSwap(wolletInfo.currentWalletMnemoinc, {
|
||||
poolId: wolletInfo.poolInfoRef.lpPublicKey,
|
||||
assetInAddress: BTC_ASSET_ADDRESS,
|
||||
assetOutAddress: USD_ASSET_ADDRESS,
|
||||
amountIn: swapAmountWithFee,
|
||||
})
|
||||
: Promise.resolve(null),
|
||||
]);
|
||||
isHoldInvoice: true,
|
||||
paymentHash,
|
||||
holdExpirySeconds: wolletInfo.holdExpirySeconds,
|
||||
includeSparkAddress: false,
|
||||
encryptedPreimage,
|
||||
});
|
||||
|
||||
if (!response.didWork) {
|
||||
throw new Error('errormessages.lightningInvoiceError');
|
||||
}
|
||||
if (!response.didWork) {
|
||||
throw new Error('errormessages.lightningInvoiceError');
|
||||
}
|
||||
|
||||
stateTracker = {
|
||||
generatedAddress: response.invoice,
|
||||
fee: 0,
|
||||
};
|
||||
stateTracker = {
|
||||
generatedAddress: response.invoice,
|
||||
fee: 0,
|
||||
};
|
||||
} else {
|
||||
const [response, swapResponse] = await Promise.all([
|
||||
sparkReceivePaymentWrapper({
|
||||
paymentType: 'lightning',
|
||||
amountSats:
|
||||
wolletInfo.endReceiveType === 'USD'
|
||||
? swapAmountWithFee
|
||||
: uniqueAmount,
|
||||
memo: wolletInfo.description,
|
||||
mnemoinc: wolletInfo.currentWalletMnemoinc,
|
||||
sendWebViewRequest,
|
||||
performSwaptoUSD: wolletInfo.endReceiveType === 'USD',
|
||||
expirySeconds:
|
||||
wolletInfo.endReceiveType === 'USD' ? 600 : undefined,
|
||||
includeSparkAddress: wolletInfo.endReceiveType !== 'USD',
|
||||
}),
|
||||
wolletInfo.endReceiveType === 'USD'
|
||||
? simulateSwap(wolletInfo.currentWalletMnemoinc, {
|
||||
poolId: wolletInfo.poolInfoRef.lpPublicKey,
|
||||
assetInAddress: BTC_ASSET_ADDRESS,
|
||||
assetOutAddress: USD_ASSET_ADDRESS,
|
||||
amountIn: swapAmountWithFee,
|
||||
})
|
||||
: Promise.resolve(null),
|
||||
]);
|
||||
|
||||
if (swapResponse && swapResponse?.didWork) {
|
||||
stateTracker.swapResponse = swapResponse.simulation;
|
||||
const showPriceImpact =
|
||||
parseFloat(swapResponse.simulation.priceImpact) > 5;
|
||||
if (showPriceImpact) {
|
||||
stateTracker.errorMessageText = {
|
||||
type: 'warning',
|
||||
text: 'errormessages.priceImpact',
|
||||
};
|
||||
if (!response.didWork) {
|
||||
throw new Error('errormessages.lightningInvoiceError');
|
||||
}
|
||||
|
||||
stateTracker = {
|
||||
generatedAddress: response.invoice,
|
||||
fee: 0,
|
||||
};
|
||||
|
||||
if (swapResponse && swapResponse?.didWork) {
|
||||
stateTracker.swapResponse = swapResponse.simulation;
|
||||
const showPriceImpact =
|
||||
parseFloat(swapResponse.simulation.priceImpact) > 5;
|
||||
if (showPriceImpact) {
|
||||
stateTracker.errorMessageText = {
|
||||
type: 'warning',
|
||||
text: 'errormessages.priceImpact',
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -794,6 +794,117 @@ export const receiveSparkLightningPayment = async ({
|
||||
}
|
||||
};
|
||||
|
||||
export const claimSparkHodlLightningPayment = async ({
|
||||
preimage,
|
||||
mnemonic,
|
||||
}) => {
|
||||
try {
|
||||
const runtime = await selectSparkRuntime(mnemonic);
|
||||
if (runtime === 'webview') {
|
||||
const response = await sendWebViewRequestGlobal(
|
||||
OPERATION_TYPES.claimSparkHodlLightningPayment,
|
||||
{
|
||||
preimage,
|
||||
mnemonic,
|
||||
},
|
||||
);
|
||||
return validateWebViewResponse(
|
||||
response,
|
||||
'Not able to get hold lightning invoice request',
|
||||
);
|
||||
} else {
|
||||
const wallet = await getWallet(mnemonic);
|
||||
const response = await wallet.claimHTLC(preimage);
|
||||
return { didWork: true, response };
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('Receive HODL lightning payment error', err);
|
||||
return { didWork: false, error: err.message };
|
||||
}
|
||||
};
|
||||
|
||||
export const querySparkHodlLightningPayments = async ({
|
||||
paymentHashes = [],
|
||||
mnemonic,
|
||||
}) => {
|
||||
try {
|
||||
const runtime = await selectSparkRuntime(mnemonic);
|
||||
if (runtime === 'webview') {
|
||||
const response = await sendWebViewRequestGlobal(
|
||||
OPERATION_TYPES.querySparkHodlLightningPayments,
|
||||
{
|
||||
paymentHashes,
|
||||
mnemonic,
|
||||
},
|
||||
);
|
||||
return validateWebViewResponse(
|
||||
response,
|
||||
'Not able to get hold lightning invoice request',
|
||||
);
|
||||
} else {
|
||||
const wallet = await getWallet(mnemonic);
|
||||
const response = await await wallet.queryHTLC({
|
||||
paymentHashes,
|
||||
limit: 50,
|
||||
offset: 0,
|
||||
});
|
||||
const paidPreimages = response.preimageRequests.map(request => ({
|
||||
status: request.status,
|
||||
createdTime: request.createdTime,
|
||||
paymentHash: Buffer.from(request.paymentHash).toString('hex'),
|
||||
transferId: request.transfer.id,
|
||||
satValue: request.transfer.totalValue,
|
||||
}));
|
||||
return { didWork: true, paidPreimages };
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('Receive HODL lightning payment error', err);
|
||||
return { didWork: false, error: err.message };
|
||||
}
|
||||
};
|
||||
|
||||
export const receiveSparkHodlLightningPayment = async ({
|
||||
amountSats,
|
||||
paymentHash,
|
||||
memo,
|
||||
expirySeconds,
|
||||
mnemonic,
|
||||
}) => {
|
||||
try {
|
||||
const runtime = await selectSparkRuntime(mnemonic);
|
||||
if (runtime === 'webview') {
|
||||
const response = await sendWebViewRequestGlobal(
|
||||
OPERATION_TYPES.receiveSparkHodlLightningPayment,
|
||||
{
|
||||
amountSats,
|
||||
paymentHash,
|
||||
memo,
|
||||
expirySeconds,
|
||||
mnemonic,
|
||||
},
|
||||
);
|
||||
return validateWebViewResponse(
|
||||
response,
|
||||
'Not able to get hold lightning invoice request',
|
||||
);
|
||||
} else {
|
||||
// createLightningHodlInvoice is native-SDK only; always use native runtime
|
||||
const wallet = await getWallet(mnemonic);
|
||||
const response = await wallet.createLightningHodlInvoice({
|
||||
amountSats,
|
||||
paymentHash,
|
||||
memo,
|
||||
expirySeconds,
|
||||
includeSparkAddress: false,
|
||||
});
|
||||
return { didWork: true, response };
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('Receive HODL lightning payment error', err);
|
||||
return { didWork: false, error: err.message };
|
||||
}
|
||||
};
|
||||
|
||||
export const getSparkLightningSendRequest = async (id, mnemonic) => {
|
||||
try {
|
||||
const runtime = await selectSparkRuntime(mnemonic);
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
getSparkPaymentFeeEstimate,
|
||||
getSparkStaticBitcoinL1Address,
|
||||
receiveSparkLightningPayment,
|
||||
receiveSparkHodlLightningPayment,
|
||||
sendSparkBitcoinPayment,
|
||||
sendSparkLightningPayment,
|
||||
sendSparkPayment,
|
||||
@@ -605,12 +606,51 @@ export const sparkReceivePaymentWrapper = async ({
|
||||
performSwaptoUSD = false,
|
||||
includeSparkAddress = true,
|
||||
expirySeconds,
|
||||
isHoldInvoice = false,
|
||||
paymentHash,
|
||||
holdExpirySeconds,
|
||||
encryptedPreimage,
|
||||
}) => {
|
||||
try {
|
||||
// if (!sparkWallet[sha256Hash(mnemoinc)])
|
||||
// throw new Error('sparkWallet not initialized');
|
||||
|
||||
if (paymentType === 'lightning') {
|
||||
if (isHoldInvoice) {
|
||||
const invoiceResponse = await receiveSparkHodlLightningPayment({
|
||||
amountSats,
|
||||
paymentHash,
|
||||
memo,
|
||||
expirySeconds: holdExpirySeconds,
|
||||
mnemonic: mnemoinc,
|
||||
});
|
||||
if (!invoiceResponse.didWork) throw new Error(invoiceResponse.error);
|
||||
const invoice = invoiceResponse.response;
|
||||
const tempTransaction = {
|
||||
id: invoice.id,
|
||||
amount: amountSats,
|
||||
expiration: invoice.invoice.expiresAt,
|
||||
description: memo || '',
|
||||
shouldNavigate,
|
||||
details: {
|
||||
createdTime: new Date(invoice.createdAt).getTime(),
|
||||
isLNURL: false,
|
||||
shouldNavigate: true,
|
||||
isBlitzContactPayment: false,
|
||||
performSwaptoUSD: false,
|
||||
isHoldInvoice: true,
|
||||
encryptedPreimage,
|
||||
paymentHash,
|
||||
},
|
||||
};
|
||||
await addSingleUnpaidSparkLightningTransaction(tempTransaction);
|
||||
return {
|
||||
didWork: true,
|
||||
data: invoice,
|
||||
invoice: invoice.invoice.encodedInvoice,
|
||||
};
|
||||
}
|
||||
|
||||
const invoiceResponse = await receiveSparkLightningPayment({
|
||||
amountSats,
|
||||
memo,
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
getSparkLightningSendRequest,
|
||||
getSparkPaymentStatus,
|
||||
getSparkTransactions,
|
||||
querySparkHodlLightningPayments,
|
||||
sparkPaymentType,
|
||||
} from '.';
|
||||
import {
|
||||
@@ -665,6 +666,10 @@ async function processLightningTransaction(
|
||||
const details = JSON.parse(txStateUpdate.details);
|
||||
const possibleOptions = unpaidInvoicesByAmount.get(details.amount) || [];
|
||||
|
||||
if (details.isHoldInvoice) {
|
||||
console.warn('Hold invoice do not check');
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!IS_SPARK_REQUEST_ID.test(txStateUpdate.sparkID) &&
|
||||
!possibleOptions.length
|
||||
@@ -972,3 +977,91 @@ async function processSparkTransactions(
|
||||
|
||||
return { updatedTxs, includesGift };
|
||||
}
|
||||
|
||||
export const checkHodlInvoicePaymentStatuses = async (
|
||||
mnemonic,
|
||||
identityPubKey,
|
||||
) => {
|
||||
try {
|
||||
const unpaidInvoices = await getAllUnpaidSparkLightningInvoices();
|
||||
if (!unpaidInvoices?.length) return;
|
||||
|
||||
const holdInvoices = unpaidInvoices
|
||||
.map(inv => ({
|
||||
...inv,
|
||||
details:
|
||||
typeof inv.details === 'string'
|
||||
? JSON.parse(inv.details)
|
||||
: inv.details,
|
||||
}))
|
||||
.filter(inv => inv.details?.isHoldInvoice === true);
|
||||
|
||||
if (!holdInvoices.length) return;
|
||||
|
||||
const paymentHashes = holdInvoices
|
||||
.map(inv => inv.details.paymentHash)
|
||||
.filter(Boolean);
|
||||
|
||||
const queryResult = await querySparkHodlLightningPayments({
|
||||
paymentHashes,
|
||||
mnemonic,
|
||||
});
|
||||
console.log(queryResult, 'query result');
|
||||
if (!queryResult.didWork || !queryResult?.paidPreimages?.length) return;
|
||||
|
||||
const txsToAdd = [];
|
||||
const idsToDelete = [];
|
||||
|
||||
for (const preimageRequest of queryResult.paidPreimages) {
|
||||
// paymentHash is Uint8Array from native SDK; may be a plain object or string via WebView JSON
|
||||
const hashHex =
|
||||
typeof preimageRequest.paymentHash === 'string'
|
||||
? preimageRequest.paymentHash
|
||||
: Buffer.from(preimageRequest.paymentHash).toString('hex');
|
||||
|
||||
const match = holdInvoices.find(
|
||||
inv => inv.details.paymentHash === hashHex,
|
||||
);
|
||||
if (!match) continue;
|
||||
if (!preimageRequest.transferId) continue;
|
||||
|
||||
// status 0 = PREIMAGE_REQUEST_STATUS_WAITING_FOR_PREIMAGE = paid but not yet claimed
|
||||
if (preimageRequest.status === 0) {
|
||||
txsToAdd.push({
|
||||
id: preimageRequest.transferId,
|
||||
paymentStatus: 'pending',
|
||||
paymentType: 'lightning',
|
||||
accountId: identityPubKey,
|
||||
details: {
|
||||
amount: match.amount || preimageRequest.satValue,
|
||||
fee: 0,
|
||||
time: preimageRequest.createdTime
|
||||
? new Date(preimageRequest.createdTime).getTime()
|
||||
: Date.now(),
|
||||
direction: 'INCOMING',
|
||||
description: match.description,
|
||||
isHoldInvoice: true,
|
||||
encryptedPreimage: match.details.encryptedPreimage,
|
||||
paymentHash: match.details.paymentHash,
|
||||
dateAddedToDb: Date.now(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Remove from pending for paid (0) and returned/expired (2) states
|
||||
if (preimageRequest.status === 0 || preimageRequest.status === 2) {
|
||||
idsToDelete.push(match.sparkID);
|
||||
}
|
||||
}
|
||||
|
||||
if (txsToAdd.length > 0) {
|
||||
await bulkUpdateSparkTransactions(txsToAdd);
|
||||
}
|
||||
|
||||
for (const sparkID of idsToDelete) {
|
||||
await deleteUnpaidSparkLightningTransaction(sparkID);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error checking hold invoice payment statuses:', err);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -242,7 +242,7 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
primaryBtnText: {
|
||||
color: '#FFFFFF',
|
||||
fontWeight: '600',
|
||||
// fontWeight: '600',
|
||||
letterSpacing: 0.1,
|
||||
},
|
||||
secondaryBtn: {
|
||||
@@ -254,7 +254,7 @@ const styles = StyleSheet.create({
|
||||
elevation: 1,
|
||||
},
|
||||
secondaryBtnText: {
|
||||
fontWeight: '600',
|
||||
// fontWeight: '600',
|
||||
fontSize: 16,
|
||||
},
|
||||
disclaimer: {
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
TouchableOpacity,
|
||||
ScrollView,
|
||||
Platform,
|
||||
ActivityIndicator,
|
||||
} from 'react-native';
|
||||
import {
|
||||
APPROXIMATE_SYMBOL,
|
||||
@@ -40,6 +41,11 @@ import CustomSettingsTopBar from '../../functions/CustomElements/settingsTopBar'
|
||||
import { currentPriceAinBToPriceDollars } from '../../functions/spark/flashnet';
|
||||
import { formatBalanceAmount } from '../../functions';
|
||||
import ThemeIcon from '../../functions/CustomElements/themeIcon';
|
||||
import { claimSparkHodlLightningPayment } from '../../functions/spark';
|
||||
import { useKeysContext } from '../../../context-store/keys';
|
||||
import { decryptMessage } from '../../functions/messaging/encodingAndDecodingMessages';
|
||||
import { useActiveCustodyAccount } from '../../../context-store/activeAccount';
|
||||
import useAdaptiveButtonLayout from '../../hooks/useAdaptiveButtonLayout';
|
||||
|
||||
export default function ExpandedTx(props) {
|
||||
const { decodedAddedContacts } = useGlobalContacts();
|
||||
@@ -53,8 +59,17 @@ export default function ExpandedTx(props) {
|
||||
const { bottomPadding } = useGlobalInsets();
|
||||
const { fiatStats } = useNodeContext();
|
||||
const { masterInfoObject } = useGlobalContextProvider();
|
||||
const { contactsPrivateKey, publicKey: contactsPublicKey } = useKeysContext();
|
||||
const [isClaimingHtlc, setIsClaimingHtlc] = useState(false);
|
||||
const { currentWalletMnemoinc } = useActiveCustodyAccount();
|
||||
const isInitialRender = useRef(true);
|
||||
|
||||
const techicalDetailsLabel = t('screens.inAccount.expandedTxPage.detailsBTN');
|
||||
const claimHTLCLabel = t('screens.inAccount.expandedTxPage.claimPayment');
|
||||
|
||||
const { shouldStack, containerProps, getLabelProps } =
|
||||
useAdaptiveButtonLayout([techicalDetailsLabel, claimHTLCLabel]);
|
||||
|
||||
const [transaction, setTransaction] = useState(
|
||||
props.route.params.transaction,
|
||||
);
|
||||
@@ -146,6 +161,41 @@ export default function ExpandedTx(props) {
|
||||
}
|
||||
};
|
||||
|
||||
const claimHTLC = async () => {
|
||||
try {
|
||||
setIsClaimingHtlc(true);
|
||||
const decodedPreimage = decryptMessage(
|
||||
contactsPrivateKey,
|
||||
contactsPublicKey,
|
||||
transaction.details.encryptedPreimage,
|
||||
);
|
||||
|
||||
const response = await claimSparkHodlLightningPayment({
|
||||
preimage: decodedPreimage,
|
||||
mnemonic: currentWalletMnemoinc,
|
||||
});
|
||||
console.log(response);
|
||||
if (response.didWork) {
|
||||
let newTx = JSON.parse(JSON.stringify(transaction));
|
||||
newTx.details.didClaimHTLC = true;
|
||||
newTx.details.preimage = decodedPreimage;
|
||||
newTx.id = transaction.sparkID;
|
||||
await bulkUpdateSparkTransactions(
|
||||
[newTx],
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
true,
|
||||
);
|
||||
setTransaction(newTx);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('Error claiming htlc in tx detials', err);
|
||||
} finally {
|
||||
setIsClaimingHtlc(false);
|
||||
}
|
||||
};
|
||||
|
||||
const isLRC20Payment = transaction.details.isLRC20Payment;
|
||||
const selectedToken = isLRC20Payment
|
||||
? sparkInformation.tokens?.[transaction.details.LRC20Token]
|
||||
@@ -465,24 +515,79 @@ export default function ExpandedTx(props) {
|
||||
{/* Description */}
|
||||
{renderDescription()}
|
||||
|
||||
{/* Details Button */}
|
||||
<CustomButton
|
||||
buttonStyles={{
|
||||
...styles.detailsButton,
|
||||
backgroundColor: theme ? COLORS.darkModeText : COLORS.primary,
|
||||
}}
|
||||
textStyles={{
|
||||
color: theme ? COLORS.lightModeText : COLORS.darkModeText,
|
||||
}}
|
||||
textContent={t('screens.inAccount.expandedTxPage.detailsBTN')}
|
||||
actionFunction={() => {
|
||||
keyboardNavigate(() => {
|
||||
navigate.navigate('TechnicalTransactionDetails', {
|
||||
transaction: transaction,
|
||||
<View
|
||||
{...containerProps}
|
||||
style={[
|
||||
styles.actionContainer,
|
||||
shouldStack
|
||||
? styles.actionContainerStacked
|
||||
: styles.actionContainerRow,
|
||||
]}
|
||||
>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
keyboardNavigate(() => {
|
||||
navigate.navigate('TechnicalTransactionDetails', {
|
||||
transaction: transaction,
|
||||
});
|
||||
});
|
||||
});
|
||||
}}
|
||||
/>
|
||||
}}
|
||||
style={[
|
||||
styles.button,
|
||||
{
|
||||
backgroundColor: theme
|
||||
? COLORS.darkModeText
|
||||
: COLORS.primary,
|
||||
},
|
||||
shouldStack ? styles.buttonStacked : styles.buttonColumn,
|
||||
]}
|
||||
>
|
||||
<ThemeText
|
||||
styles={{
|
||||
includeFontPadding: false,
|
||||
color: theme ? COLORS.lightModeText : COLORS.darkModeText,
|
||||
}}
|
||||
{...getLabelProps(0)}
|
||||
content={techicalDetailsLabel}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
{transaction.details.isHoldInvoice &&
|
||||
isPending &&
|
||||
!transaction.details.didClaimHTLC && (
|
||||
<TouchableOpacity
|
||||
onPress={claimHTLC}
|
||||
style={[
|
||||
styles.button,
|
||||
{
|
||||
backgroundColor: theme
|
||||
? COLORS.darkModeText
|
||||
: COLORS.primary,
|
||||
},
|
||||
shouldStack ? styles.buttonStacked : styles.buttonColumn,
|
||||
]}
|
||||
disabled={isClaimingHtlc}
|
||||
>
|
||||
{isClaimingHtlc ? (
|
||||
<ActivityIndicator
|
||||
color={
|
||||
theme ? COLORS.lightModeText : COLORS.darkModeText
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<ThemeText
|
||||
styles={{
|
||||
includeFontPadding: false,
|
||||
color: theme
|
||||
? COLORS.lightModeText
|
||||
: COLORS.darkModeText,
|
||||
}}
|
||||
{...getLabelProps(1)}
|
||||
content={claimHTLCLabel}
|
||||
/>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
|
||||
{/* Receipt Dots */}
|
||||
<ReceiptDots screenDimensions={screenDimensions} />
|
||||
@@ -821,12 +926,6 @@ const styles = StyleSheet.create({
|
||||
borderRadius: 8,
|
||||
},
|
||||
|
||||
detailsButton: {
|
||||
width: 'auto',
|
||||
...CENTER,
|
||||
marginVertical: 24,
|
||||
borderRadius: 8,
|
||||
},
|
||||
receiptDotsContainer: {
|
||||
position: 'absolute',
|
||||
bottom: Platform.OS === 'ios' ? -10 : -8,
|
||||
@@ -859,11 +958,6 @@ const styles = StyleSheet.create({
|
||||
padding: 4,
|
||||
},
|
||||
|
||||
memoInput: {
|
||||
fontSize: SIZES.medium,
|
||||
minHeight: 76,
|
||||
textAlignVertical: 'top',
|
||||
},
|
||||
actionButtons: {
|
||||
width: '100%',
|
||||
flexDirection: 'row',
|
||||
@@ -878,4 +972,35 @@ const styles = StyleSheet.create({
|
||||
fontSize: SIZES.medium,
|
||||
includeFontPadding: false,
|
||||
},
|
||||
|
||||
actionContainer: {
|
||||
width: '100%',
|
||||
gap: 10,
|
||||
alignItems: 'center',
|
||||
marginVertical: 20,
|
||||
},
|
||||
actionContainerRow: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
actionContainerStacked: {
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'flex-start',
|
||||
},
|
||||
button: {
|
||||
minHeight: 50,
|
||||
paddingHorizontal: 12,
|
||||
borderRadius: 12,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
buttonColumn: {
|
||||
flex: 1,
|
||||
},
|
||||
buttonStacked: {
|
||||
width: '100%',
|
||||
},
|
||||
disabled: {
|
||||
opacity: 0.4,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -45,6 +45,8 @@ import { dollarsToSats, satsToDollars } from '../../functions/spark/flashnet';
|
||||
import ThemeIcon from '../../functions/CustomElements/themeIcon';
|
||||
import { useGlobalInsets } from '../../../context-store/insetsProvider';
|
||||
import { shareMessage } from '../../functions/handleShare';
|
||||
import { useKeysContext } from '../../../context-store/keys';
|
||||
import DropdownMenu from '../../functions/CustomElements/dropdownMenu';
|
||||
|
||||
export default function ReceivePaymentHome(props) {
|
||||
const navigate = useNavigation();
|
||||
@@ -64,6 +66,8 @@ export default function ReceivePaymentHome(props) {
|
||||
const { startLiquidEventListener } = useLiquidEvent();
|
||||
const userReceiveAmount = props.route.params?.receiveAmount || 0;
|
||||
const [initialSendAmount, setInitialSendAmount] = useState(userReceiveAmount);
|
||||
const [holdExpirySeconds, setHoldExpirySeconds] = useState(2592000);
|
||||
const { contactsPrivateKey, publicKey: contactsPublicKey } = useKeysContext();
|
||||
const { bottomPadding } = useGlobalInsets();
|
||||
const isSharingRef = useRef(null);
|
||||
|
||||
@@ -87,6 +91,7 @@ export default function ReceivePaymentHome(props) {
|
||||
? ''
|
||||
: `${globalContactsInformation.myProfile.uniqueName}@blitzwalletapp.com`,
|
||||
isGeneratingInvoice: false,
|
||||
isHoldInvoice: false,
|
||||
minMaxSwapAmount: {
|
||||
min: 0,
|
||||
max: 0,
|
||||
@@ -104,6 +109,38 @@ export default function ReceivePaymentHome(props) {
|
||||
addressStateRef.current = addressState;
|
||||
}, [addressState]);
|
||||
|
||||
const handleHoldToggle = useCallback(() => {
|
||||
if (!addressState.isHoldInvoice) {
|
||||
// Turning ON — show explanation first
|
||||
navigate.navigate('InformationPopup', {
|
||||
textContent: t('screens.inAccount.receiveBtcPage.holdInvoiceExplainer'),
|
||||
buttonText: t('constants.understandText'),
|
||||
customNavigation: () => proceedWithHoldToggle(true),
|
||||
});
|
||||
return;
|
||||
}
|
||||
proceedWithHoldToggle(false);
|
||||
}, [addressState.isHoldInvoice]);
|
||||
|
||||
const proceedWithHoldToggle = useCallback(async newValue => {
|
||||
if (newValue) navigate.goBack();
|
||||
setAddressState(prev => ({
|
||||
...prev,
|
||||
isHoldInvoice: newValue,
|
||||
generatedAddress: '',
|
||||
isGeneratingInvoice: newValue,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const handleExpirySelect = useCallback(async seconds => {
|
||||
setAddressState(prev => ({
|
||||
...prev,
|
||||
generatedAddress: '',
|
||||
isGeneratingInvoice: true,
|
||||
}));
|
||||
setHoldExpirySeconds(seconds.value);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
async function runAddressInit() {
|
||||
crashlyticsLogReport('Begining adddress initialization');
|
||||
@@ -116,7 +153,9 @@ export default function ReceivePaymentHome(props) {
|
||||
prevRequstInfo.current.selectedRecieveOption.toLowerCase() &&
|
||||
paymentDescription === prevRequstInfo.current.paymentDescription &&
|
||||
!addressStateRef.current.errorMessageText.text &&
|
||||
endReceiveType === prevRequstInfo.current.endReceiveType
|
||||
endReceiveType === prevRequstInfo.current.endReceiveType &&
|
||||
addressState.isHoldInvoice === prevRequstInfo.current.isHoldInvoice &&
|
||||
holdExpirySeconds === prevRequstInfo.current.holdExpirySeconds
|
||||
) {
|
||||
// This checks if we had a previous requst
|
||||
// And all other formation is the same
|
||||
@@ -130,13 +169,16 @@ export default function ReceivePaymentHome(props) {
|
||||
selectedRecieveOption,
|
||||
paymentDescription,
|
||||
endReceiveType,
|
||||
isHoldInvoice: addressState.isHoldInvoice,
|
||||
holdExpirySeconds,
|
||||
};
|
||||
if (
|
||||
!userReceiveAmount &&
|
||||
selectedRecieveOption.toLowerCase() === 'lightning' &&
|
||||
!isUsingAltAccount &&
|
||||
endReceiveType === 'BTC' &&
|
||||
!paymentDescription
|
||||
!paymentDescription &&
|
||||
!addressState.isHoldInvoice
|
||||
) {
|
||||
setInitialSendAmount(0);
|
||||
setAddressState(prev => ({
|
||||
@@ -166,6 +208,10 @@ export default function ReceivePaymentHome(props) {
|
||||
setInitialSendAmount,
|
||||
userReceiveAmount,
|
||||
poolInfoRef,
|
||||
isHoldInvoice: addressState.isHoldInvoice,
|
||||
holdExpirySeconds,
|
||||
contactsPrivateKey,
|
||||
contactsPublicKey,
|
||||
});
|
||||
if (selectedRecieveOption === 'Liquid') {
|
||||
startLiquidEventListener(60);
|
||||
@@ -180,6 +226,8 @@ export default function ReceivePaymentHome(props) {
|
||||
selectedRecieveOption,
|
||||
requestUUID,
|
||||
endReceiveType,
|
||||
addressState.isHoldInvoice,
|
||||
holdExpirySeconds,
|
||||
]);
|
||||
|
||||
const headerContext =
|
||||
@@ -251,6 +299,10 @@ export default function ReceivePaymentHome(props) {
|
||||
isSharingRef={isSharingRef}
|
||||
paymentDescription={paymentDescription}
|
||||
userReceiveAmount={userReceiveAmount}
|
||||
handleHoldToggle={handleHoldToggle}
|
||||
handleExpirySelect={handleExpirySelect}
|
||||
isHoldInvoice={addressState.isHoldInvoice}
|
||||
holdExpirySeconds={holdExpirySeconds}
|
||||
/>
|
||||
|
||||
<ButtonsContainer
|
||||
@@ -406,17 +458,22 @@ function QrCode(props) {
|
||||
isSharingRef,
|
||||
paymentDescription,
|
||||
userReceiveAmount,
|
||||
handleHoldToggle,
|
||||
handleExpirySelect,
|
||||
isHoldInvoice,
|
||||
holdExpirySeconds,
|
||||
} = props;
|
||||
const { showToast } = useToast();
|
||||
const { theme } = useGlobalThemeContext();
|
||||
const { backgroundOffset, textColor } = GetThemeColors();
|
||||
const { backgroundOffset, textColor, backgroundColor } = GetThemeColors();
|
||||
|
||||
const isUsingLnurl =
|
||||
selectedRecieveOption.toLowerCase() === 'lightning' &&
|
||||
!initialSendAmount &&
|
||||
!isUsingAltAccount &&
|
||||
endReceiveType === 'BTC' &&
|
||||
!paymentDescription;
|
||||
!paymentDescription &&
|
||||
!isHoldInvoice;
|
||||
|
||||
const qrOpacity = useSharedValue(addressState.generatedAddress ? 1 : 0);
|
||||
const loadingOpacity = useSharedValue(isUsingLnurl ? 0 : 1);
|
||||
@@ -601,7 +658,9 @@ function QrCode(props) {
|
||||
}}
|
||||
>
|
||||
<QrCodeWrapper
|
||||
outerContainerStyle={{ backgroundColor: 'transparent' }}
|
||||
outerContainerStyle={{
|
||||
backgroundColor: 'transparent',
|
||||
}}
|
||||
QRData={qrData}
|
||||
/>
|
||||
</Animated.View>
|
||||
@@ -713,6 +772,90 @@ function QrCode(props) {
|
||||
/>
|
||||
)}
|
||||
|
||||
{selectedRecieveOption?.toLowerCase() === 'lightning' &&
|
||||
endReceiveType !== 'USD' && (
|
||||
<>
|
||||
<QRInformationRow
|
||||
title={t('screens.inAccount.receiveBtcPage.confirmToClaimTitle')}
|
||||
info={
|
||||
isHoldInvoice
|
||||
? t('screens.inAccount.receiveBtcPage.confirmToClaimOn')
|
||||
: t('screens.inAccount.receiveBtcPage.confirmToClaimOff')
|
||||
}
|
||||
customNumberOfLines={5}
|
||||
iconName={isHoldInvoice ? 'LockOpen' : 'Lock'}
|
||||
showBoder={true}
|
||||
actionFunction={handleHoldToggle}
|
||||
/>
|
||||
{isHoldInvoice && (
|
||||
<View
|
||||
style={[
|
||||
styles.qrInfoContainer,
|
||||
{
|
||||
gap: 25,
|
||||
borderBottomWidth: 2,
|
||||
borderBottomColor: backgroundColor,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<ThemeText
|
||||
styles={{
|
||||
flexGrow: 1,
|
||||
includeFontPadding: false,
|
||||
fontSize: SIZES.small,
|
||||
}}
|
||||
content={t('screens.inAccount.receiveBtcPage.expiryTitle')}
|
||||
/>
|
||||
<DropdownMenu
|
||||
options={[
|
||||
{
|
||||
label: t('screens.inAccount.receiveBtcPage.expiry_86400'),
|
||||
value: 86400,
|
||||
},
|
||||
{
|
||||
label: t(
|
||||
'screens.inAccount.receiveBtcPage.expiry_604800',
|
||||
),
|
||||
value: 604800,
|
||||
},
|
||||
{
|
||||
label: t(
|
||||
'screens.inAccount.receiveBtcPage.expiry_2592000',
|
||||
),
|
||||
value: 2592000,
|
||||
},
|
||||
{
|
||||
label: t(
|
||||
'screens.inAccount.receiveBtcPage.expiry_7776000',
|
||||
),
|
||||
value: 7776000,
|
||||
},
|
||||
]}
|
||||
customVericalArrowsColor={textColor}
|
||||
selectedValue={t(
|
||||
`screens.inAccount.receiveBtcPage.expiry_${holdExpirySeconds}`,
|
||||
)}
|
||||
onSelect={handleExpirySelect}
|
||||
showClearIcon={false}
|
||||
translateLabelText={false}
|
||||
showVerticalArrows={true}
|
||||
showVerticalArrowsAbsolute={true}
|
||||
customButtonStyles={{
|
||||
backgroundColor,
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
dropdownItemCustomStyles={{
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
globalContainerStyles={{
|
||||
flexShrink: 1,
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
<QRInformationRow
|
||||
title={t('screens.inAccount.receiveBtcPage.invoiceDescription', {
|
||||
context: invoiceContext,
|
||||
@@ -741,31 +884,14 @@ function QrCode(props) {
|
||||
function QRInformationRow({
|
||||
title = '',
|
||||
info = '',
|
||||
lightModeIcon,
|
||||
darkModeIcon,
|
||||
lightsOutIcon,
|
||||
showBoder,
|
||||
actionFunction,
|
||||
showSkeleton = false,
|
||||
rotateIcon = false,
|
||||
iconName,
|
||||
customNumberOfLines = 1,
|
||||
}) {
|
||||
const { backgroundColor, textColor } = GetThemeColors();
|
||||
|
||||
const [layout, setLayout] = useState({ height: 5 });
|
||||
const maxLayoutRef = useRef({ height: 5 });
|
||||
|
||||
const handleLayoutMeasurement = useCallback(event => {
|
||||
const { height } = event.nativeEvent.layout;
|
||||
|
||||
const newMaxHeight = Math.max(maxLayoutRef.current.height, height);
|
||||
|
||||
if (newMaxHeight !== maxLayoutRef.current.height) {
|
||||
maxLayoutRef.current = { height: newMaxHeight };
|
||||
setLayout({ height: newMaxHeight });
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
@@ -779,102 +905,52 @@ function QRInformationRow({
|
||||
if (actionFunction) actionFunction();
|
||||
}}
|
||||
>
|
||||
{/* Hidden component for layout measurement */}
|
||||
<View
|
||||
style={{ position: 'absolute', opacity: 0, pointerEvents: 'none' }}
|
||||
onLayout={handleLayoutMeasurement}
|
||||
>
|
||||
<View style={styles.infoTextContiner}>
|
||||
<ThemeText
|
||||
styles={{ includeFontPadding: false, fontSize: SIZES.small }}
|
||||
content={title}
|
||||
/>
|
||||
{showSkeleton ? (
|
||||
<SkeletonPlaceholder
|
||||
highlightColor={backgroundColor}
|
||||
backgroundColor={COLORS.opaicityGray}
|
||||
enabled={true}
|
||||
speed={SKELETON_ANIMATION_SPEED}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
height: SIZES.small,
|
||||
marginVertical: 3,
|
||||
borderRadius: 8,
|
||||
}}
|
||||
></View>
|
||||
</SkeletonPlaceholder>
|
||||
) : (
|
||||
<ThemeText
|
||||
CustomNumberOfLines={1}
|
||||
styles={{
|
||||
includeFontPadding: false,
|
||||
fontSize: SIZES.small,
|
||||
opacity: 0.6,
|
||||
flexShrink: 1,
|
||||
<View style={styles.infoTextContiner}>
|
||||
<ThemeText
|
||||
CustomNumberOfLines={customNumberOfLines}
|
||||
styles={{ includeFontPadding: false, fontSize: SIZES.small }}
|
||||
content={title}
|
||||
/>
|
||||
{showSkeleton ? (
|
||||
<SkeletonPlaceholder
|
||||
highlightColor={backgroundColor}
|
||||
backgroundColor={COLORS.opaicityGray}
|
||||
enabled={true}
|
||||
speed={SKELETON_ANIMATION_SPEED}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
height: SIZES.medium,
|
||||
marginVertical: 3,
|
||||
borderRadius: 8,
|
||||
}}
|
||||
content={info}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</SkeletonPlaceholder>
|
||||
) : (
|
||||
<ThemeText
|
||||
CustomNumberOfLines={customNumberOfLines}
|
||||
styles={{
|
||||
includeFontPadding: false,
|
||||
fontSize: SIZES.small,
|
||||
opacity: 0.6,
|
||||
}}
|
||||
content={info}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
|
||||
{/* Visible component with fixed height */}
|
||||
<View
|
||||
style={{
|
||||
height: layout.height,
|
||||
width: 30,
|
||||
height: 30,
|
||||
backgroundColor,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: '100%',
|
||||
flexDirection: 'row',
|
||||
borderRadius: 8,
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
<View style={styles.infoTextContiner}>
|
||||
<ThemeText
|
||||
styles={{ includeFontPadding: false, fontSize: SIZES.small }}
|
||||
content={title}
|
||||
/>
|
||||
{showSkeleton ? (
|
||||
<SkeletonPlaceholder
|
||||
highlightColor={backgroundColor}
|
||||
backgroundColor={COLORS.opaicityGray}
|
||||
enabled={true}
|
||||
speed={SKELETON_ANIMATION_SPEED}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
height: SIZES.medium,
|
||||
marginVertical: 3,
|
||||
borderRadius: 8,
|
||||
}}
|
||||
></View>
|
||||
</SkeletonPlaceholder>
|
||||
) : (
|
||||
<ThemeText
|
||||
CustomNumberOfLines={1}
|
||||
styles={{
|
||||
includeFontPadding: false,
|
||||
fontSize: SIZES.small,
|
||||
opacity: 0.6,
|
||||
flexShrink: 1,
|
||||
}}
|
||||
content={info}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
width: 30,
|
||||
height: 30,
|
||||
backgroundColor,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
borderRadius: 8,
|
||||
}}
|
||||
>
|
||||
<ThemeIcon colorOverride={textColor} size={15} iconName={iconName} />
|
||||
</View>
|
||||
<ThemeIcon colorOverride={textColor} size={15} iconName={iconName} />
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
@@ -939,11 +1015,10 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingVertical: 10,
|
||||
minHeight: 45,
|
||||
minHeight: 50,
|
||||
},
|
||||
infoTextContiner: {
|
||||
width: '100%',
|
||||
flexShrink: 1,
|
||||
flex: 1,
|
||||
marginRight: 10,
|
||||
},
|
||||
dollarPrice: {
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
} from '../app/functions/spark/transactions';
|
||||
import { useAppStatus } from './appStatus';
|
||||
import {
|
||||
checkHodlInvoicePaymentStatuses,
|
||||
fullRestoreSparkState,
|
||||
updateSparkTxStatus,
|
||||
} from '../app/functions/spark/restore';
|
||||
@@ -819,14 +820,6 @@ const SparkWalletProvider = ({ children }) => {
|
||||
details: JSON.parse(lastAddedTx.details),
|
||||
};
|
||||
|
||||
if (handledNavigatedTxs.current.has(parsedTx.sparkID)) {
|
||||
console.log(
|
||||
'Already handled transaction, skipping confirm tx page navigation',
|
||||
);
|
||||
return;
|
||||
}
|
||||
handledNavigatedTxs.current.add(parsedTx.sparkID);
|
||||
|
||||
const details = parsedTx?.details;
|
||||
|
||||
if (isFlashnetTransfer(parsedTx.sparkID)) {
|
||||
@@ -872,6 +865,19 @@ const SparkWalletProvider = ({ children }) => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (details.isHoldInvoice && parsedTx.paymentStatus !== 'completed') {
|
||||
console.log('Blocking unconfirmed hodl invoice from showing');
|
||||
return;
|
||||
}
|
||||
|
||||
if (handledNavigatedTxs.current.has(parsedTx.sparkID)) {
|
||||
console.log(
|
||||
'Already handled transaction, skipping confirm tx page navigation',
|
||||
);
|
||||
return;
|
||||
}
|
||||
handledNavigatedTxs.current.add(parsedTx.sparkID);
|
||||
|
||||
const isOnReceivePage =
|
||||
navigationRef
|
||||
.getRootState()
|
||||
@@ -1151,6 +1157,11 @@ const SparkWalletProvider = ({ children }) => {
|
||||
if (isInitialLRC20Run.current) {
|
||||
isInitialLRC20Run.current = false;
|
||||
}
|
||||
|
||||
await checkHodlInvoicePaymentStatuses(
|
||||
currentMnemonicRef.current,
|
||||
sparkInfoRef.current.identityPubKey,
|
||||
);
|
||||
} catch (err) {
|
||||
console.error('Error during periodic restore:', err);
|
||||
}
|
||||
|
||||
@@ -59,6 +59,9 @@ export const OPERATION_TYPES = {
|
||||
getSingleTxDetails: 'getSingleTxDetails',
|
||||
createSatsInvoice: 'createSatsInvoice',
|
||||
createTokensInvoice: 'createTokensInvoice',
|
||||
claimSparkHodlLightningPayment: 'claimSparkHodlLightningPayment',
|
||||
receiveSparkHodlLightningPayment: 'receiveSparkHodlLightningPayment',
|
||||
querySparkHodlLightningPayments: 'querySparkHodlLightningPayments',
|
||||
|
||||
// Flashnet
|
||||
initializeFlashnet: 'initializeFlashnet',
|
||||
@@ -105,6 +108,8 @@ const longOperations = [
|
||||
OPERATION_TYPES.requestClawback,
|
||||
OPERATION_TYPES.runLeafOptimization,
|
||||
OPERATION_TYPES.runTokenOptimization,
|
||||
OPERATION_TYPES.claimSparkHodlLightningPayment,
|
||||
OPERATION_TYPES.receiveSparkHodlLightningPayment,
|
||||
];
|
||||
|
||||
const mediumOperations = [
|
||||
|
||||
@@ -1784,7 +1784,8 @@
|
||||
"detailsBTN": "Technische Details",
|
||||
"contactPaymentType": "Kontakt",
|
||||
"converstionRate": "{{satAmount}} pro {{USDAmount}}",
|
||||
"gift": "Geschenk"
|
||||
"gift": "Geschenk",
|
||||
"claimPayment": "Zahlung einfordern"
|
||||
},
|
||||
"explorePage": {
|
||||
"timeLeft": "({{time}} verbleibend)",
|
||||
@@ -1833,7 +1834,18 @@
|
||||
"selectReceiveAssetHead": "Bitte wählen Sie das Asset zum Empfangen aus.",
|
||||
"usd_convert_warning": "Der endgültige Betrag, den Sie erhalten, kann sich aufgrund von Marktpreisänderungen während der Umwandlung ändern.",
|
||||
"editDescriptionHead": "Was möchten Sie sagen?",
|
||||
"editDescriptionPlaceholder": "Beschreibung hinzufügen"
|
||||
"editDescriptionPlaceholder": "Beschreibung hinzufügen",
|
||||
"confirmToClaimTitle": "Vor dem Empfang bestätigen",
|
||||
"confirmToClaimOff": "Aus, Zahlungen werden sofort bestätigt",
|
||||
"confirmToClaimOn": "An, du bestätigst jede Zahlung",
|
||||
"holdInvoiceExplainer": "Wenn aktiviert, werden an diese Rechnung gesendete Zahlungen zurückgehalten, bis du sie bestätigst. Wenn du sie nicht rechtzeitig einforderst, wird die Zahlung automatisch an den Absender zurückgesendet.",
|
||||
"expiryTitle": "Läuft ab nach",
|
||||
"expiry_3600": "1 Stunde",
|
||||
"expiry_21600": "6 Stunden",
|
||||
"expiry_86400": "24 Stunden",
|
||||
"expiry_604800": "7 Tage",
|
||||
"expiry_2592000": "30 Tage",
|
||||
"expiry_7776000": "90 Tage"
|
||||
},
|
||||
"settingsContent": {
|
||||
"about": "Über uns",
|
||||
|
||||
@@ -1814,7 +1814,8 @@
|
||||
"detailsBTN": "Technical details",
|
||||
"contactPaymentType": "Contact",
|
||||
"converstionRate": "{{satAmount}} per {{dollarAmount}}",
|
||||
"gift": "Gift"
|
||||
"gift": "Gift",
|
||||
"claimPayment": "Claim payment"
|
||||
},
|
||||
"explorePage": {
|
||||
"timeLeft": "({{time}} left)",
|
||||
@@ -1866,7 +1867,18 @@
|
||||
"selectReceiveAssetHead": "Select the currency to receive",
|
||||
"usd_convert_warning": "The final amount you receive may vary due to market price changes during the conversion.",
|
||||
"editDescriptionHead": "What would you like to say?",
|
||||
"editDescriptionPlaceholder": "Add a description"
|
||||
"editDescriptionPlaceholder": "Add a description",
|
||||
"confirmToClaimTitle": "Confirm before receiving",
|
||||
"confirmToClaimOff": "Off, payments are confirmed instantly",
|
||||
"confirmToClaimOn": "On, you approve each payment",
|
||||
"holdInvoiceExplainer": "When on, payments sent to this invoice are held untill you confirm them. If you don't claim in time, the payment automatically returns to the sender.",
|
||||
"expiryTitle": "Expires after",
|
||||
"expiry_3600": "1 hour",
|
||||
"expiry_21600": "6 hours",
|
||||
"expiry_86400": "24 hours",
|
||||
"expiry_604800": "7 days",
|
||||
"expiry_2592000": "30 days",
|
||||
"expiry_7776000": "90 days"
|
||||
},
|
||||
|
||||
"settingsContent": {
|
||||
|
||||
+18
-24
@@ -129,7 +129,6 @@
|
||||
"details": "Detalles",
|
||||
"total": "Total"
|
||||
},
|
||||
|
||||
"languages": {
|
||||
"english": "English",
|
||||
"spanish": "Español",
|
||||
@@ -140,7 +139,6 @@
|
||||
"swedish": "Svenska",
|
||||
"russian": "Русский"
|
||||
},
|
||||
|
||||
"weekdays": {
|
||||
"Mon": "Lunes",
|
||||
"Tue": "Martes",
|
||||
@@ -568,7 +566,6 @@
|
||||
"errorMessage": "Lo sentimos, no pudimos guardar tu conversación."
|
||||
}
|
||||
},
|
||||
|
||||
"giftCards": {
|
||||
"giftCardsPage": {
|
||||
"searchPlaceholder": "Buscar una tarjeta de regalo",
|
||||
@@ -582,7 +579,6 @@
|
||||
"price": "Precio: ",
|
||||
"fee": "Tarifa: "
|
||||
},
|
||||
|
||||
"createAccount": {
|
||||
"title": "Con tecnología de",
|
||||
"saveEmail": "No tienes un correo electrónico guardado. Acelera el proceso de pago guardando un correo.",
|
||||
@@ -801,10 +797,10 @@
|
||||
"whatArePools": "¿Qué son los pools?",
|
||||
"whatArePoolsBody": "Los pools te permiten reunir pagos en Bitcoin para un objetivo compartido. Crea un pool, establece un monto objetivo y compártelo con quien quieras.",
|
||||
"howItWorks": "Cómo funciona",
|
||||
"howStep1": "\u2022 Crea un nuevo pool con un nombre y un monto objetivo",
|
||||
"howStep2": "\u2022 Comparte el enlace del pool para que otros puedan encontrarlo",
|
||||
"howStep3": "\u2022 Los contribuyentes envían Bitcoin directamente al pool",
|
||||
"howStep4": "\u2022 Cierra el pool cuando estés listo para mover los fondos a tu wallet"
|
||||
"howStep1": "• Crea un nuevo pool con un nombre y un monto objetivo",
|
||||
"howStep2": "• Comparte el enlace del pool para que otros puedan encontrarlo",
|
||||
"howStep3": "• Los contribuyentes envían Bitcoin directamente al pool",
|
||||
"howStep4": "• Cierra el pool cuando estés listo para mover los fondos a tu wallet"
|
||||
}
|
||||
},
|
||||
"manualInputPage": {
|
||||
@@ -869,7 +865,6 @@
|
||||
"usernameInputDesc": "Editar nombre de usuario"
|
||||
}
|
||||
},
|
||||
|
||||
"sendPages": {
|
||||
"sendPaymentScreen": {
|
||||
"initialLoadingMessage": "Preparación de detalles de facturas",
|
||||
@@ -1281,12 +1276,10 @@
|
||||
"flashnet": "BTC <> USD",
|
||||
"pageTitle": "Transferencias de {{type}}"
|
||||
},
|
||||
|
||||
"viewRoostockSwaps": {
|
||||
"loadingMessage": "Cargando transferencias de Roostock guardadas",
|
||||
"noSwapsMessage": "No tienes transferencias de Roostock guardadas"
|
||||
},
|
||||
|
||||
"rootstockSwapInfo": {
|
||||
"title": "Intercambio Submarino",
|
||||
"id": "ID",
|
||||
@@ -1651,7 +1644,8 @@
|
||||
"detailsBTN": "Detalles técnicos",
|
||||
"contactPaymentType": "Contacto",
|
||||
"converstionRate": "{{satAmount}} por {{dollarAmount}}",
|
||||
"gift": "Regalo"
|
||||
"gift": "Regalo",
|
||||
"claimPayment": "Reclamar pago"
|
||||
},
|
||||
"explorePage": {
|
||||
"timeLeft": "({{time}} restantes)",
|
||||
@@ -1700,7 +1694,18 @@
|
||||
"selectReceiveAssetHead": "Selecciona el activo a recibir",
|
||||
"usd_convert_warning": "El monto final que recibas puede variar debido a cambios en el precio del mercado durante la conversión.",
|
||||
"editDescriptionHead": "¿Qué te gustaría decir?",
|
||||
"editDescriptionPlaceholder": "Agregar una descripción"
|
||||
"editDescriptionPlaceholder": "Agregar una descripción",
|
||||
"confirmToClaimTitle": "Confirmar antes de recibir",
|
||||
"confirmToClaimOff": "Desactivado, los pagos se confirman al instante",
|
||||
"confirmToClaimOn": "Activado, apruebas cada pago",
|
||||
"holdInvoiceExplainer": "Cuando está activado, los pagos enviados a esta factura se retienen hasta que los confirmes. Si no los reclamas a tiempo, el pago se devuelve automáticamente al remitente.",
|
||||
"expiryTitle": "Expira después de",
|
||||
"expiry_3600": "1 hora",
|
||||
"expiry_21600": "6 horas",
|
||||
"expiry_86400": "24 horas",
|
||||
"expiry_604800": "7 días",
|
||||
"expiry_2592000": "30 días",
|
||||
"expiry_7776000": "90 días"
|
||||
},
|
||||
"settingsContent": {
|
||||
"about": "Acerca de",
|
||||
@@ -1775,7 +1780,6 @@
|
||||
"title": "Regalos en Blitz",
|
||||
"desc": "Comparte Bitcoin o dólares con amigos y familia"
|
||||
},
|
||||
|
||||
"giftsOverview": {
|
||||
"noGiftsHead": "Aún no hay regalos",
|
||||
"noGiftsDesc": "Crea tu primer regalo para compartir Bitcoin o dólares con amigos y familiares.",
|
||||
@@ -1785,7 +1789,6 @@
|
||||
"unclaimed": "No canjeado",
|
||||
"reclaimed": "Recuperado"
|
||||
},
|
||||
|
||||
"createGift": {
|
||||
"noAmountError": "Ingresa un monto para crear tu regalo.",
|
||||
"connectError": "No pudimos configurar tu billetera del regalo. Inténtalo de nuevo.",
|
||||
@@ -1802,7 +1805,6 @@
|
||||
"durationText": "{{numDays}} días",
|
||||
"type": "Tipo"
|
||||
},
|
||||
|
||||
"giftConfirmation": {
|
||||
"header": "¡Regalo creado!",
|
||||
"whatToDo": "Comparte este regalo con cualquiera usando el código QR o el enlace",
|
||||
@@ -1813,7 +1815,6 @@
|
||||
"createAnother": "Crear otro",
|
||||
"done": "Listo"
|
||||
},
|
||||
|
||||
"claimHome": {
|
||||
"header": "Ingresa el enlace del regalo",
|
||||
"desc": "Pega el enlace que recibiste o escanea el código QR para reclamar tu regalo",
|
||||
@@ -1822,7 +1823,6 @@
|
||||
"noGiftLinkError": "No pudimos encontrar un enlace de regalo. Escanea o pega el enlace que recibiste.",
|
||||
"invliadGiftFormat": "Enlace de regalo no válido. Copia el enlace completo e inténtalo de nuevo."
|
||||
},
|
||||
|
||||
"reclaimPage": {
|
||||
"header": "Recupera tu regalo",
|
||||
"desc": "Ingresa o selecciona el ID del regalo para devolver un regalo expirado o no reclamado.",
|
||||
@@ -1832,7 +1832,6 @@
|
||||
"noReclaimsMessage": "No tienes regalos vencidos en este momento. Vuelve cuando algún regalo haya vencido para recuperarlo.",
|
||||
"advancedModeBTN": "Modo avanzado"
|
||||
},
|
||||
|
||||
"advancedMode": {
|
||||
"header": "Modo avanzado",
|
||||
"currentIndexHead": "Índice actual del regalo",
|
||||
@@ -1844,7 +1843,6 @@
|
||||
"restoreGiftBTN": "Restaurar regalo",
|
||||
"advancedWarning": "Esta función avanzada solo debe usarse cuando el proceso normal de recuperación no funciona. Si no estás seguro, prueba primero la página de recuperación normal."
|
||||
},
|
||||
|
||||
"claimPage": {
|
||||
"parseError": "No pudimos leer los detalles del regalo desde este enlace.",
|
||||
"noGiftForReclaim": "No encontramos este regalo. Puede que ya haya sido reclamado.",
|
||||
@@ -2018,11 +2016,9 @@
|
||||
"loadingText": "Estamos configurando todo. ¡Espera un momento! Esto podría tardar hasta un minuto.",
|
||||
"errorText1": "Error al conectar con tu nodo. Intenta recargar la app."
|
||||
},
|
||||
|
||||
"swapMessages": {
|
||||
"liquid": "Transferencia de Liquid a Spark"
|
||||
},
|
||||
|
||||
"tabs": {
|
||||
"home": "Billetera",
|
||||
"appStore": "Tienda",
|
||||
@@ -2053,11 +2049,9 @@
|
||||
"giftCard": "{{name}} te envió una tarjeta regalo de {{giftCardName}}."
|
||||
}
|
||||
},
|
||||
|
||||
"accountCard": {
|
||||
"fallbackAccountName": "Cuenta {{index}}"
|
||||
},
|
||||
|
||||
"flashnetUserMessages": {
|
||||
"FSAG-1000": "La solicitud no superó las validaciones.",
|
||||
"FSAG-1001": "Falta un campo obligatorio en tu solicitud.",
|
||||
|
||||
@@ -936,10 +936,10 @@
|
||||
"whatArePools": "Qu’est-ce qu’un pool ?",
|
||||
"whatArePoolsBody": "Les pools vous permettent de collecter des paiements en Bitcoin pour un objectif commun. Créez un pool, définissez un montant cible et partagez-le avec qui vous voulez.",
|
||||
"howItWorks": "Comment ça fonctionne",
|
||||
"howStep1": "\u2022 Créez un nouveau pool avec un nom et un montant cible",
|
||||
"howStep2": "\u2022 Partagez le lien du pool pour que d’autres puissent le trouver",
|
||||
"howStep3": "\u2022 Les contributeurs envoient des bitcoins directement au pool",
|
||||
"howStep4": "\u2022 Fermez le pool lorsque vous êtes prêt à transférer les fonds vers votre wallet"
|
||||
"howStep1": "• Créez un nouveau pool avec un nom et un montant cible",
|
||||
"howStep2": "• Partagez le lien du pool pour que d’autres puissent le trouver",
|
||||
"howStep3": "• Les contributeurs envoient des bitcoins directement au pool",
|
||||
"howStep4": "• Fermez le pool lorsque vous êtes prêt à transférer les fonds vers votre wallet"
|
||||
}
|
||||
},
|
||||
"manualInputPage": {
|
||||
@@ -1782,7 +1782,8 @@
|
||||
"detailsBTN": "Détails techniques",
|
||||
"contactPaymentType": "Contact",
|
||||
"converstionRate": "{{satAmount}} par {{dollarAmount}}",
|
||||
"gift": "Cadeau"
|
||||
"gift": "Cadeau",
|
||||
"claimPayment": "Réclamer le paiement"
|
||||
},
|
||||
"explorePage": {
|
||||
"timeLeft": "({{time}} restantes)",
|
||||
@@ -1831,7 +1832,18 @@
|
||||
"selectReceiveAssetHead": "Sélectionnez l’actif à recevoir",
|
||||
"usd_convert_warning": "Le montant final que vous recevrez peut varier en raison des fluctuations du prix du marché pendant la conversion.",
|
||||
"editDescriptionHead": "Que souhaitez-vous dire?",
|
||||
"editDescriptionPlaceholder": "Ajouter une description"
|
||||
"editDescriptionPlaceholder": "Ajouter une description",
|
||||
"confirmToClaimTitle": "Confirmer avant de recevoir",
|
||||
"confirmToClaimOff": "Désactivé, les paiements sont confirmés instantanément",
|
||||
"confirmToClaimOn": "Activé, vous approuvez chaque paiement",
|
||||
"holdInvoiceExplainer": "Lorsqu’elle est activée, les paiements envoyés à cette facture sont retenus jusqu’à ce que vous les confirmiez. Si vous ne les réclamez pas à temps, le paiement est automatiquement renvoyé à l’expéditeur.",
|
||||
"expiryTitle": "Expire après",
|
||||
"expiry_3600": "1 heure",
|
||||
"expiry_21600": "6 heures",
|
||||
"expiry_86400": "24 heures",
|
||||
"expiry_604800": "7 jours",
|
||||
"expiry_2592000": "30 jours",
|
||||
"expiry_7776000": "90 jours"
|
||||
},
|
||||
"settingsContent": {
|
||||
"about": "A propos de",
|
||||
|
||||
@@ -936,10 +936,10 @@
|
||||
"whatArePools": "Cosa sono i pool?",
|
||||
"whatArePoolsBody": "I pool ti permettono di raccogliere pagamenti in Bitcoin per un obiettivo condiviso. Crea un pool, imposta un importo obiettivo e condividilo con chi vuoi.",
|
||||
"howItWorks": "Come funziona",
|
||||
"howStep1": "\u2022 Crea un nuovo pool con un nome e un importo obiettivo",
|
||||
"howStep2": "\u2022 Condividi il link del pool affinché altri possano trovarlo",
|
||||
"howStep3": "\u2022 I contributori inviano Bitcoin direttamente al pool",
|
||||
"howStep4": "\u2022 Chiudi il pool quando sei pronto a trasferire i fondi al tuo wallet"
|
||||
"howStep1": "• Crea un nuovo pool con un nome e un importo obiettivo",
|
||||
"howStep2": "• Condividi il link del pool affinché altri possano trovarlo",
|
||||
"howStep3": "• I contributori inviano Bitcoin direttamente al pool",
|
||||
"howStep4": "• Chiudi il pool quando sei pronto a trasferire i fondi al tuo wallet"
|
||||
}
|
||||
},
|
||||
"manualInputPage": {
|
||||
@@ -1782,7 +1782,8 @@
|
||||
"contactPaymentType": "Contatto",
|
||||
"converstionRate": "{{satAmount}} per {{dollarAmount}}",
|
||||
"confirmMessage_sent": "Importo inviato",
|
||||
"gift": "Regalo"
|
||||
"gift": "Regalo",
|
||||
"claimPayment": "Richiedi pagamento"
|
||||
},
|
||||
"explorePage": {
|
||||
"timeLeft": "({{time}} rimanenti)",
|
||||
@@ -1831,7 +1832,18 @@
|
||||
"selectReceiveAssetHead": "Seleziona l’asset da ricevere",
|
||||
"usd_convert_warning": "L'importo finale che riceverai può variare a causa delle variazioni di prezzo di mercato durante la conversione.",
|
||||
"editDescriptionHead": "Cosa vorresti dire?",
|
||||
"editDescriptionPlaceholder": "Aggiungi una descrizione"
|
||||
"editDescriptionPlaceholder": "Aggiungi una descrizione",
|
||||
"confirmToClaimTitle": "Conferma prima di ricevere",
|
||||
"confirmToClaimOff": "Disattivato, i pagamenti sono confermati immediatamente",
|
||||
"confirmToClaimOn": "Attivato, approvi ogni pagamento",
|
||||
"holdInvoiceExplainer": "Quando è attivo, i pagamenti inviati a questa fattura vengono trattenuti finché non li confermi. Se non li richiedi in tempo, il pagamento viene automaticamente restituito al mittente.",
|
||||
"expiryTitle": "Scade dopo",
|
||||
"expiry_3600": "1 ora",
|
||||
"expiry_21600": "6 ore",
|
||||
"expiry_86400": "24 ore",
|
||||
"expiry_604800": "7 giorni",
|
||||
"expiry_2592000": "30 giorni",
|
||||
"expiry_7776000": "90 giorni"
|
||||
},
|
||||
"settingsContent": {
|
||||
"about": "Informazioni",
|
||||
|
||||
+12
-50
@@ -128,7 +128,6 @@
|
||||
"details": "세부사항",
|
||||
"total": "합계"
|
||||
},
|
||||
|
||||
"languages": {
|
||||
"english": "English",
|
||||
"spanish": "Español",
|
||||
@@ -139,7 +138,6 @@
|
||||
"swedish": "Svenska",
|
||||
"russian": "русский"
|
||||
},
|
||||
|
||||
"weekdays": {
|
||||
"Mon": "Monday",
|
||||
"Tue": "Tuesday",
|
||||
@@ -149,7 +147,6 @@
|
||||
"Sat": "Saturday",
|
||||
"Sun": "Sunday"
|
||||
},
|
||||
|
||||
"months": {
|
||||
"Jan": "January",
|
||||
"Feb": "February",
|
||||
@@ -164,7 +161,6 @@
|
||||
"Nov": "November",
|
||||
"Dec": "December"
|
||||
},
|
||||
|
||||
"timeLabels": {
|
||||
"minute": "minute",
|
||||
"minutes": "minutes",
|
||||
@@ -179,7 +175,6 @@
|
||||
"monthly": "Monthly",
|
||||
"yearly": "Yearly"
|
||||
},
|
||||
|
||||
"transactionLabelText": {
|
||||
"notSent": "Payment not sent",
|
||||
"txTime_just_now": "Just now",
|
||||
@@ -204,7 +199,6 @@
|
||||
"memo": "Memo",
|
||||
"roostockSwap": "Rootstock to Spark Transfer"
|
||||
},
|
||||
|
||||
"createAccount": {
|
||||
"chooseLanguage": {
|
||||
"title": "Choose Language"
|
||||
@@ -269,7 +263,6 @@
|
||||
"btn": "I understand"
|
||||
}
|
||||
},
|
||||
|
||||
"adminLogin": {
|
||||
"pinPage": {
|
||||
"isBiometricEnabledConfirmAction": "We couldn’t verify your biometrics.\n\nDo you want to delete all wallet data? Only continue if your seed phrase is securely backed up.",
|
||||
@@ -279,7 +272,6 @@
|
||||
"biometricsHeader": "Open with Biometrics"
|
||||
}
|
||||
},
|
||||
|
||||
"apps": {
|
||||
"appList": {
|
||||
"AI": "AI",
|
||||
@@ -387,14 +379,12 @@
|
||||
"price": "Price: ",
|
||||
"fee": "Fee: "
|
||||
},
|
||||
|
||||
"switchModel": {
|
||||
"inputLabel": "Input: {{amount}}/M",
|
||||
"outputLabel": "Output: {{amount}}/M",
|
||||
"chooseModel": "Choose Model",
|
||||
"noModels": "No models match that name. Please check the spelling or try a different name."
|
||||
},
|
||||
|
||||
"exampleSearchCards": {
|
||||
"title": "Example Search Cards",
|
||||
"examples": [
|
||||
@@ -700,7 +690,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"saveChat": {
|
||||
"errorMessage": "Sorry, we could not save your conversation."
|
||||
}
|
||||
@@ -718,7 +707,6 @@
|
||||
"price": "Price: ",
|
||||
"fee": "Fee: "
|
||||
},
|
||||
|
||||
"createAccount": {
|
||||
"title": "Powered by",
|
||||
"saveEmail": "You do not have an email saved. Speed up the checkout process by saving an email.",
|
||||
@@ -758,7 +746,6 @@
|
||||
"customCopyMessage": "Support email copied"
|
||||
}
|
||||
},
|
||||
|
||||
"sms4sats": {
|
||||
"home": {
|
||||
"pageDescription": "Send and receive SMS messages without giving away your personal phone number.",
|
||||
@@ -771,7 +758,6 @@
|
||||
"invalidNumber": "Not a valid phone number",
|
||||
"receiveTitle": "Confirm Receive"
|
||||
},
|
||||
|
||||
"sendPage": {
|
||||
"startingSendingMessage": "Creating send order",
|
||||
"phoneNumberInputDescription": "Enter phone number",
|
||||
@@ -850,7 +836,6 @@
|
||||
"addListing": "Add Shop"
|
||||
}
|
||||
},
|
||||
|
||||
"wallet": {
|
||||
"halfModal": {
|
||||
"images": "From Image",
|
||||
@@ -900,7 +885,6 @@
|
||||
"format": "Other receiving methods",
|
||||
"infoMessage": "Custom amounts aren’t supported on Spark or Rootstock payments."
|
||||
},
|
||||
|
||||
"switchReceiveOptionPage": {
|
||||
"title": "Receiving methods",
|
||||
"actionBTN": "Show {{action}}",
|
||||
@@ -956,7 +940,6 @@
|
||||
"timeoutError": "The process took too long to complete. Please try again.",
|
||||
"payingToSameAddress": "You cannot send a {{addressType}} payment to yourself"
|
||||
},
|
||||
|
||||
"errorScreen": {
|
||||
"ok": "OK",
|
||||
"title": "Error message"
|
||||
@@ -966,7 +949,6 @@
|
||||
"backTextToAmount": "{{amount}}",
|
||||
"tenMinutes": "{{numMins}} minutes"
|
||||
},
|
||||
|
||||
"selectLRC20Token": {
|
||||
"title": "Select Token",
|
||||
"searchPlaceholder": "Token name...",
|
||||
@@ -998,7 +980,6 @@
|
||||
"see_all_txs": "See all transactions",
|
||||
"no_transaction_history": "Send or receive a transaction for it to show up here"
|
||||
},
|
||||
|
||||
"lrc20Assets": {
|
||||
"actionText": "{{action}} tokens",
|
||||
"tokensSearchPlaceholder": "Search tokens...",
|
||||
@@ -1033,7 +1014,6 @@
|
||||
"loadingMessage": "Loading saved transactions"
|
||||
}
|
||||
},
|
||||
|
||||
"contacts": {
|
||||
"contactsPage": {
|
||||
"contactsHeader": "Contacts",
|
||||
@@ -1055,7 +1035,6 @@
|
||||
"noProfilesFound": "No profiles match this search",
|
||||
"startTypingMessage": "Search by a Lightning address (e.g. name@service.com) or a Blitz username."
|
||||
},
|
||||
|
||||
"expandedContactPage": {
|
||||
"loadingContactError": "Unable to load contact, please try again.",
|
||||
"requestLNURLError": "You can only request money from Blitz contacts, not Lightning addresses.",
|
||||
@@ -1082,7 +1061,6 @@
|
||||
"deleteProfileImageError": "Unable to delete profile image, please try again.",
|
||||
"deleateWarning": "Are you sure you want to delete this contact? Messages older than a week cannot be restored."
|
||||
},
|
||||
|
||||
"sendAndRequestPage": {
|
||||
"profileMessage": "Paying {{name}}",
|
||||
"contactMessage": "{{name}} paid you",
|
||||
@@ -1112,13 +1090,11 @@
|
||||
"claimed": "Used",
|
||||
"markAsClaimed": "Mark as Used"
|
||||
},
|
||||
|
||||
"selectGiftPage": {
|
||||
"noCards": "No cards available",
|
||||
"header": "Select the Gift Card you want to send",
|
||||
"inputPlaceholder": "Search for a Gift Card"
|
||||
},
|
||||
|
||||
"internalComponents": {
|
||||
"addOrDeleteImageScreen": {
|
||||
"pageMessage": "Do you want to {{option}} {{option2}} photo"
|
||||
@@ -1151,7 +1127,6 @@
|
||||
"scanProfile": "Scan Profile"
|
||||
}
|
||||
},
|
||||
|
||||
"settings": {
|
||||
"index": {
|
||||
"editProfile": "Edit Profile",
|
||||
@@ -1274,7 +1249,6 @@
|
||||
"crashreporting_disabled": "Disabled crash reporting",
|
||||
"descriptionText": "Crash data helps us improve the stability and performance of our application.\n\nWhen a crash occurs, the device information that is automatically recorded includes:\n\n• Operating System: OS version, device orientation, and jailbreak status\n• Device Details: Model, orientation, and available RAM\n• Crash Information: Date of the crash and the app version"
|
||||
},
|
||||
|
||||
"accounts": {
|
||||
"inputPlaceholder": "Search existing account",
|
||||
"mainWalletPlace": "Main Wallet"
|
||||
@@ -1311,7 +1285,6 @@
|
||||
"flashnet": "BTC <> USD",
|
||||
"pageTitle": "{{type}} Transfers"
|
||||
},
|
||||
|
||||
"viewRoostockSwaps": {
|
||||
"loadingMessage": "Loading saved Roostock transfers",
|
||||
"noSwapsMessage": "You have no saved Roostock transfers"
|
||||
@@ -1326,7 +1299,6 @@
|
||||
"invoice": "Invoice",
|
||||
"refundSwap": "Refund transfer"
|
||||
},
|
||||
|
||||
"viewAllLiquidSwaps": {
|
||||
"rescanComplete": "Rescan complete",
|
||||
"swapStartedMessage": "The transfer has started. It may take 10–20 seconds for the payment to show up.",
|
||||
@@ -1376,7 +1348,6 @@
|
||||
"othersType": "All other",
|
||||
"othersFee": "Network Fees"
|
||||
},
|
||||
|
||||
"nip5": {
|
||||
"noNameError": "Name cannot be empty.",
|
||||
"noPubKey": "Public key cannot be empty.",
|
||||
@@ -1422,7 +1393,6 @@
|
||||
"createConnection": "",
|
||||
"connectionName": ""
|
||||
},
|
||||
|
||||
"hasNoAccounts": {
|
||||
"wanringMessage": "To send money from your Nostr Connect wallet, you’ll first need to add funds—either by receiving money or transferring from your main wallet.\n\n You can transfer funds from your main wallet to NWC in the account settings page."
|
||||
},
|
||||
@@ -1566,7 +1536,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"screens": {
|
||||
"inAccount": {
|
||||
"appStore": {
|
||||
@@ -1578,7 +1547,6 @@
|
||||
"featuredApps": "Anything you want here?",
|
||||
"comingSoon": "This feature is temporarily unavailable. We're working to restore it as soon as possible."
|
||||
},
|
||||
|
||||
"confirmTxPage": {
|
||||
"failedToSend": "Failed to send",
|
||||
"confirmMessage": "{{direction}} successfully",
|
||||
@@ -1607,7 +1575,6 @@
|
||||
"percentOfGoal": "{{goalPercent}}% of goal",
|
||||
"numAddedUsers": "+{{numNewUsers}} users today"
|
||||
},
|
||||
|
||||
"loadingScreen": {
|
||||
"loadingMessage1": "Please don't close the app",
|
||||
"loadingMessage2": "We are setting things up",
|
||||
@@ -1619,7 +1586,6 @@
|
||||
"dbInitError1": "We’re unable to set up your app.",
|
||||
"dbInitError2": "Please try again. If this issue continues, you can safely recover your funds using your seed phrase."
|
||||
},
|
||||
|
||||
"receiveBtcPage": {
|
||||
"onchainFeeMessage": "Payments received to Bitcoin addresses have a network fee and a 0.1% Spark fee.\n\nIf you send money to yourself, you'll pay the network fee twice — once to send it and once to claim it.\n\nIf someone else sends you money, you'll only pay the network fee once to claim it.",
|
||||
"liquidFeeMessage": "Payments received to Liquid addresses need to be transferred into Spark.\n\nThis process includes a lockup fee of about {{fee}}, a claim fee of around {{claimFee}}, and a 0.1% service fee from Boltz based on the amount you're sending.",
|
||||
@@ -1647,9 +1613,19 @@
|
||||
"header_liquid": "Bitcoin via Liquid",
|
||||
"header_rootstock": "Bitcoin via Rootstock",
|
||||
"selectReceiveAssetHead": "Select the currency to receive",
|
||||
"usd_convert_warning": "The final amount you receive may vary due to market price changes during the conversion."
|
||||
"usd_convert_warning": "The final amount you receive may vary due to market price changes during the conversion.",
|
||||
"confirmToClaimTitle": "Confirm to claim",
|
||||
"confirmToClaimOff": "Off",
|
||||
"confirmToClaimOn": "On — payment waits for you",
|
||||
"holdInvoiceExplainer": "When on, payments sent to this invoice are held for up to 24 hours. You'll get a notification to claim them. If you don't claim in time, the payment automatically returns to the sender.",
|
||||
"expiryTitle": "Expires after",
|
||||
"expiry_3600": "1 hour",
|
||||
"expiry_21600": "6 hours",
|
||||
"expiry_86400": "24 hours",
|
||||
"expiry_604800": "7 days",
|
||||
"expiry_2592000": "30 days",
|
||||
"expiry_7776000": "90 days"
|
||||
},
|
||||
|
||||
"settingsContent": {
|
||||
"about": "About",
|
||||
"language": "Language",
|
||||
@@ -1692,7 +1668,6 @@
|
||||
"viewAllTxPage": {
|
||||
"title": "Transactions"
|
||||
},
|
||||
|
||||
"lrc20HalfModal": {
|
||||
"title": "Search Tokens",
|
||||
"searchPlaceholder": "Token name...",
|
||||
@@ -1718,11 +1693,9 @@
|
||||
"shareMessage": "You've received a {{amount}} gift! Claim it here:\n{{link}}",
|
||||
"fundGiftMessage": "Creating Gift",
|
||||
"reclaimGiftMessage": "Reclaiming Gift",
|
||||
|
||||
"giftsHome": {
|
||||
"title": "Blitz Gifts"
|
||||
},
|
||||
|
||||
"giftsOverview": {
|
||||
"noGiftsHead": "No gifts yet",
|
||||
"noGiftsDesc": "Create your first gift to share Bitcoin or Dollars with friends and family",
|
||||
@@ -1732,7 +1705,6 @@
|
||||
"unclaimed": "Unclaimed",
|
||||
"reclaimed": "Reclaimed"
|
||||
},
|
||||
|
||||
"createGift": {
|
||||
"noAmountError": "Please enter an amount to create your gift.",
|
||||
"connectError": "We couldn’t set up your gift wallet. Please try again.",
|
||||
@@ -1749,7 +1721,6 @@
|
||||
"durationText": "{{numDays}} days",
|
||||
"type": "Type"
|
||||
},
|
||||
|
||||
"giftConfirmation": {
|
||||
"header": "Gift Created!",
|
||||
"whatToDo": "Share this gift with anyone using the QR code or link below",
|
||||
@@ -1893,7 +1864,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"toastmessages": {
|
||||
"confirmCopy": "Copied to clipboard",
|
||||
"failedCopy": "Failed to copy",
|
||||
@@ -1902,7 +1872,6 @@
|
||||
"desc": "Your balance will update shortly"
|
||||
}
|
||||
},
|
||||
|
||||
"errormessages": {
|
||||
"nointernet": "Please reconnect to the internet to use this feature",
|
||||
"genericError": "An unexpected error occurred",
|
||||
@@ -1957,7 +1926,6 @@
|
||||
"paymentFeeError": "We couldn’t retrieve the payment fee. Please try again. If the issue continues, close the app and reopen it before trying again.",
|
||||
"priceImpact": "This payment is large, so the final amount you receive in Dollars may change."
|
||||
},
|
||||
|
||||
"loadingScreen": {
|
||||
"message1": "Please don't close the app",
|
||||
"message2": "We are setting things up",
|
||||
@@ -1972,7 +1940,6 @@
|
||||
"share": {
|
||||
"contact": "Hi, add me on Blitz!"
|
||||
},
|
||||
|
||||
"swapMessages": {
|
||||
"liquid": "Liquid to Spark Transfer"
|
||||
},
|
||||
@@ -1998,21 +1965,18 @@
|
||||
"giftCard": "{{name}} sent you a {{giftCardName}} Gift Card"
|
||||
}
|
||||
},
|
||||
|
||||
"flashnetUserMessages": {
|
||||
"FSAG-1000": "The request failed validation checks.",
|
||||
"FSAG-1001": "A required field is missing from your request.",
|
||||
"FSAG-1002": "One or more fields have an invalid format.",
|
||||
"FSAG-1003": "A value is outside the acceptable range.",
|
||||
"FSAG-1004": "This value already exists and must be unique.",
|
||||
|
||||
"FSAG-2001": "Your request signature could not be verified.",
|
||||
"FSAG-2002": "The token identity doesn't match the expected public key.",
|
||||
"FSAG-2003": "Authentication is required for this operation.",
|
||||
"FSAG-2004": "Your session has expired or the token is invalid.",
|
||||
"FSAG-2005": "The request nonce is invalid or has already been used.",
|
||||
"FSAG-2101": "The provided public key is invalid.",
|
||||
|
||||
"FSAG-3001": "A temporary service issue occurred. Please try again.",
|
||||
"FSAG-3002": "A temporary service issue occurred. Please try again.",
|
||||
"FSAG-3101": "A database error occurred. Please try again.",
|
||||
@@ -2024,7 +1988,6 @@
|
||||
"FSAG-3302": "The AMM processor timed out while processing your request.",
|
||||
"FSAG-3401": "An internal processing error occurred.",
|
||||
"FSAG-3402": "An internal processing error occurred.",
|
||||
|
||||
"FSAG-4001": "The specified pool does not exist.",
|
||||
"FSAG-4002": "The specified host namespace does not exist.",
|
||||
"FSAG-4101": "Your authentication session was not found or has expired.",
|
||||
@@ -2035,7 +1998,6 @@
|
||||
"FSAG-4204": "You don't have enough LP tokens to complete this withdrawal.",
|
||||
"FSAG-4301": "The fee configuration is invalid.",
|
||||
"FSAG-4401": "This Spark transfer has already been used in an operation.",
|
||||
|
||||
"FSAG-5001": "An internal error occurred while processing your request.",
|
||||
"FSAG-5002": "This feature is not yet available.",
|
||||
"FSAG-5003": "An internal error occurred. Please contact support if this persists.",
|
||||
|
||||
@@ -936,10 +936,10 @@
|
||||
"whatArePools": "O que são Vaquinhas?",
|
||||
"whatArePoolsBody": "As Vaquinhas permitem que você colete pagamentos em Bitcoin para um objetivo qualquer. Crie uma Vaquinha, defina um valor alvo e compartilhe com quem quiser.",
|
||||
"howItWorks": "Como funciona",
|
||||
"howStep1": "\u2022 Crie uma nova Vaquinha com um nome e um valor alvo",
|
||||
"howStep2": "\u2022 Compartilhe o link da Vaquinha com outras pessoas",
|
||||
"howStep3": "\u2022 Os contribuidores enviam Bitcoin diretamente para a Vaquinha",
|
||||
"howStep4": "\u2022 Encerre a Vaquinha quando estiver pronto para mover os fundos para sua carteira"
|
||||
"howStep1": "• Crie uma nova Vaquinha com um nome e um valor alvo",
|
||||
"howStep2": "• Compartilhe o link da Vaquinha com outras pessoas",
|
||||
"howStep3": "• Os contribuidores enviam Bitcoin diretamente para a Vaquinha",
|
||||
"howStep4": "• Encerre a Vaquinha quando estiver pronto para mover os fundos para sua carteira"
|
||||
}
|
||||
},
|
||||
"manualInputPage": {
|
||||
@@ -1782,7 +1782,8 @@
|
||||
"detailsBTN": "Detalhes técnicos",
|
||||
"contactPaymentType": "Contato",
|
||||
"converstionRate": "{{satAmount}} por {{dollarAmount}}",
|
||||
"gift": "Vale-Blitz"
|
||||
"gift": "Vale-Blitz",
|
||||
"claimPayment": "Reivindicar pagamento"
|
||||
},
|
||||
"explorePage": {
|
||||
"timeLeft": "({{time}} restantes)",
|
||||
@@ -1831,7 +1832,18 @@
|
||||
"selectReceiveAssetHead": "O que você deseja receber?",
|
||||
"usd_convert_warning": "O valor final que você receber pode variar devido a mudanças no preço de mercado durante a conversão.",
|
||||
"editDescriptionHead": "Adicione uma descrição para esse pagamento",
|
||||
"editDescriptionPlaceholder": "Adicionar uma descrição"
|
||||
"editDescriptionPlaceholder": "Adicionar uma descrição",
|
||||
"confirmToClaimTitle": "Confirmar antes de receber",
|
||||
"confirmToClaimOff": "Desativado, os pagamentos são confirmados instantaneamente",
|
||||
"confirmToClaimOn": "Ativado, você aprova cada pagamento",
|
||||
"holdInvoiceExplainer": "Quando ativado, os pagamentos enviados para esta fatura ficam retidos até que você os confirme. Se você não reivindicar a tempo, o pagamento retorna automaticamente ao remetente.",
|
||||
"expiryTitle": "Expira após",
|
||||
"expiry_3600": "1 hora",
|
||||
"expiry_21600": "6 horas",
|
||||
"expiry_86400": "24 horas",
|
||||
"expiry_604800": "7 dias",
|
||||
"expiry_2592000": "30 dias",
|
||||
"expiry_7776000": "90 dias"
|
||||
},
|
||||
"settingsContent": {
|
||||
"about": "Sobre",
|
||||
|
||||
@@ -936,10 +936,10 @@
|
||||
"whatArePools": "Что такое пулы?",
|
||||
"whatArePoolsBody": "Пулы позволяют собирать платежи в биткоинах для общей цели. Создайте пул, установите целевую сумму и поделитесь им с кем угодно.",
|
||||
"howItWorks": "Как это работает",
|
||||
"howStep1": "\u2022 Создайте новый пул с названием и целевой суммой",
|
||||
"howStep2": "\u2022 Поделитесь ссылкой на пул, чтобы другие могли его найти",
|
||||
"howStep3": "\u2022 Участники отправляют биткоины напрямую в пул",
|
||||
"howStep4": "\u2022 Закройте пул, когда будете готовы перевести средства в свою wallet"
|
||||
"howStep1": "• Создайте новый пул с названием и целевой суммой",
|
||||
"howStep2": "• Поделитесь ссылкой на пул, чтобы другие могли его найти",
|
||||
"howStep3": "• Участники отправляют биткоины напрямую в пул",
|
||||
"howStep4": "• Закройте пул, когда будете готовы перевести средства в свою wallet"
|
||||
}
|
||||
},
|
||||
"manualInputPage": {
|
||||
@@ -1783,7 +1783,8 @@
|
||||
"detailsBTN": "Тех. детали",
|
||||
"contactPaymentType": "Контакт",
|
||||
"converstionRate": "{{satAmount}} за {{dollarAmount}}",
|
||||
"gift": "Подарок"
|
||||
"gift": "Подарок",
|
||||
"claimPayment": "Получить платёж"
|
||||
},
|
||||
"explorePage": {
|
||||
"timeLeft": "(осталось {{time}})",
|
||||
@@ -1832,7 +1833,18 @@
|
||||
"selectReceiveAssetHead": "Выберите актив для получения",
|
||||
"usd_convert_warning": "Окончательная сумма, которую вы получите, может измениться из-за колебаний рыночной цены во время конвертации.",
|
||||
"editDescriptionHead": "Что вы хотите сказать?",
|
||||
"editDescriptionPlaceholder": "Добавить описание"
|
||||
"editDescriptionPlaceholder": "Добавить описание",
|
||||
"confirmToClaimTitle": "Подтвердить перед получением",
|
||||
"confirmToClaimOff": "Выключено, платежи подтверждаются мгновенно",
|
||||
"confirmToClaimOn": "Включено, вы подтверждаете каждый платёж",
|
||||
"holdInvoiceExplainer": "Если включено, платежи, отправленные по этому счёту, удерживаются до вашего подтверждения. Если вы не получите платёж вовремя, он автоматически возвращается отправителю.",
|
||||
"expiryTitle": "Истекает через",
|
||||
"expiry_3600": "1 час",
|
||||
"expiry_21600": "6 часов",
|
||||
"expiry_86400": "24 часа",
|
||||
"expiry_604800": "7 дней",
|
||||
"expiry_2592000": "30 дней",
|
||||
"expiry_7776000": "90 дней"
|
||||
},
|
||||
"settingsContent": {
|
||||
"about": "О приложении",
|
||||
|
||||
@@ -936,10 +936,10 @@
|
||||
"whatArePools": "Vad är pools?",
|
||||
"whatArePoolsBody": "Pools låter dig samla in Bitcoin-betalningar för ett gemensamt mål. Skapa en pool, ange ett målbelopp och dela den med vem du vill.",
|
||||
"howItWorks": "Så fungerar det",
|
||||
"howStep1": "\u2022 Skapa en ny pool med ett namn och ett målbelopp",
|
||||
"howStep2": "\u2022 Dela poolens länk så att andra kan hitta den",
|
||||
"howStep3": "\u2022 Bidragsgivare skickar Bitcoin direkt till poolen",
|
||||
"howStep4": "\u2022 Stäng poolen när du är redo att flytta medlen till din wallet"
|
||||
"howStep1": "• Skapa en ny pool med ett namn och ett målbelopp",
|
||||
"howStep2": "• Dela poolens länk så att andra kan hitta den",
|
||||
"howStep3": "• Bidragsgivare skickar Bitcoin direkt till poolen",
|
||||
"howStep4": "• Stäng poolen när du är redo att flytta medlen till din wallet"
|
||||
}
|
||||
},
|
||||
"manualInputPage": {
|
||||
@@ -1782,7 +1782,8 @@
|
||||
"detailsBTN": "Tekniska detaljer",
|
||||
"contactPaymentType": "Kontakt",
|
||||
"converstionRate": "{{satAmount}} per {{dollarAmount}}",
|
||||
"gift": "Gåva"
|
||||
"gift": "Gåva",
|
||||
"claimPayment": "Ta emot betalning"
|
||||
},
|
||||
"explorePage": {
|
||||
"timeLeft": "({{time}} kvar)",
|
||||
@@ -1831,7 +1832,18 @@
|
||||
"selectReceiveAssetHead": "Välj tillgång att ta emot",
|
||||
"usd_convert_warning": "Det slutliga beloppet du får kan variera på grund av marknadsprisförändringar under konverteringen.",
|
||||
"editDescriptionHead": "Vad vill du säga?",
|
||||
"editDescriptionPlaceholder": "Lägg till en beskrivning"
|
||||
"editDescriptionPlaceholder": "Lägg till en beskrivning",
|
||||
"confirmToClaimTitle": "Bekräfta innan mottagning",
|
||||
"confirmToClaimOff": "Av, betalningar bekräftas direkt",
|
||||
"confirmToClaimOn": "På, du godkänner varje betalning",
|
||||
"holdInvoiceExplainer": "När det är aktiverat hålls betalningar som skickas till denna faktura tills du bekräftar dem. Om du inte gör anspråk i tid returneras betalningen automatiskt till avsändaren.",
|
||||
"expiryTitle": "Upphör efter",
|
||||
"expiry_3600": "1 timme",
|
||||
"expiry_21600": "6 timmar",
|
||||
"expiry_86400": "24 timmar",
|
||||
"expiry_604800": "7 dagar",
|
||||
"expiry_2592000": "30 dagar",
|
||||
"expiry_7776000": "90 dagar"
|
||||
},
|
||||
"settingsContent": {
|
||||
"about": "Om",
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@
|
||||
"react-native-webview": "13.15.0",
|
||||
"react-native-worklets": "0.5.1",
|
||||
"rn-qr-generator": "^2.0.0",
|
||||
"spark-web-context": "https://github.com/blitzwallet/spark-web-context.git#87e547f9de6f2f8cfdd956dfb89989e9a36378b3",
|
||||
"spark-web-context": "https://github.com/blitzwallet/spark-web-context.git#d97589eb04b1535b26fd843aefa3c96eaf7fcd6e",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"text-encoding": "^0.7.0",
|
||||
"text-encoding-polyfill": "^0.6.7",
|
||||
|
||||
@@ -4871,7 +4871,7 @@ __metadata:
|
||||
react-native-worklets: 0.5.1
|
||||
react-test-renderer: 19.1.0
|
||||
rn-qr-generator: ^2.0.0
|
||||
spark-web-context: "https://github.com/blitzwallet/spark-web-context.git#87e547f9de6f2f8cfdd956dfb89989e9a36378b3"
|
||||
spark-web-context: "https://github.com/blitzwallet/spark-web-context.git#d97589eb04b1535b26fd843aefa3c96eaf7fcd6e"
|
||||
stream-browserify: ^3.0.0
|
||||
text-encoding: ^0.7.0
|
||||
text-encoding-polyfill: ^0.6.7
|
||||
@@ -13820,16 +13820,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"spark-web-context@https://github.com/blitzwallet/spark-web-context.git#87e547f9de6f2f8cfdd956dfb89989e9a36378b3":
|
||||
"spark-web-context@https://github.com/blitzwallet/spark-web-context.git#d97589eb04b1535b26fd843aefa3c96eaf7fcd6e":
|
||||
version: 1.0.0
|
||||
resolution: "spark-web-context@https://github.com/blitzwallet/spark-web-context.git#commit=87e547f9de6f2f8cfdd956dfb89989e9a36378b3"
|
||||
resolution: "spark-web-context@https://github.com/blitzwallet/spark-web-context.git#commit=d97589eb04b1535b26fd843aefa3c96eaf7fcd6e"
|
||||
dependencies:
|
||||
"@buildonspark/spark-sdk": ^0.6.5
|
||||
"@ecies/ciphers": ^0.2.4
|
||||
"@flashnet/sdk": ^0.5.6
|
||||
"@noble/hashes": ^2.0.1
|
||||
"@noble/secp256k1": ^3.0.0
|
||||
checksum: 4f00be7fbcafb445099e992d113b4b1fcaa53c0a9752c4b9d6f3bbf599f25f526e3b81da647fcabc805853ac47f7ba68f34d74e53dd7162011ee4e6c363b27bd
|
||||
checksum: 384a3e430bd2c1c5129611e4d60a2210ecb9d48c039ee73f0945fd04dd1efacd0f45c237d8b0aa72913719d0131106fe32ba906ed401d1c13d29d868c26a7807
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in New Issue
Block a user