diff --git a/examples/wallet-api/package.json b/examples/wallet-api/package.json index 06e4ef1ba..c486b8667 100644 --- a/examples/wallet-api/package.json +++ b/examples/wallet-api/package.json @@ -9,10 +9,11 @@ "start:sign-message": "FILE=sign-message.html yarn start", "start:sign-cis3-message": "FILE=sign-cis3-message.html yarn start", "start:web3-id": "FILE=web3-id.html yarn start", - "start:sign-token-update": "FILE=sign-token-update.html yarn start" + "start:sign-token-update": "FILE=sign-token-update.html yarn start", + "start:sponsored-transaction": "FILE=sponsored-transaction.html yarn start" }, "dependencies": { - "@concordium/web-sdk": "10.0.2" + "@concordium/web-sdk": "^12.0.1" }, "devDependencies": { "live-server": "^1.2.2" diff --git a/examples/wallet-api/sign-token-update.html b/examples/wallet-api/sign-token-update.html index 8b55d33b6..f2fecefe4 100644 --- a/examples/wallet-api/sign-token-update.html +++ b/examples/wallet-api/sign-token-update.html @@ -30,8 +30,15 @@ }); document.getElementById('signSingleTransferTokenUpdate').addEventListener('click', () => { - const { TokenOperationType, Cbor, TokenAmount, TokenHolder, CborMemo, TokenId, AccountAddress } = - concordiumSDK; + const { + TokenOperationType, + Cbor, + TokenAmount, + CborAccountAddress, + CborMemo, + TokenId, + AccountAddress, + } = concordiumSDK; const ops = [ { @@ -40,7 +47,7 @@ value: '1000000', decimals: 6, }), - recipient: TokenHolder.fromAccountAddress( + recipient: CborAccountAddress.fromAccountAddress( AccountAddress.fromBase58('4PVJxxtiNVanfuNgvFWtFT1JCiqoVs6npVXBqwLNKprqnUiC2A') ), memo: CborMemo.fromString('Some text for memo'), @@ -62,8 +69,15 @@ }); document.getElementById('signTokenUpdate').addEventListener('click', () => { - const { TokenOperationType, Cbor, TokenAmount, TokenHolder, CborMemo, TokenId, AccountAddress } = - concordiumSDK; + const { + TokenOperationType, + Cbor, + TokenAmount, + CborAccountAddress, + CborMemo, + TokenId, + AccountAddress, + } = concordiumSDK; const ops = [ { @@ -72,7 +86,7 @@ value: '1000000', decimals: 6, }), - recipient: TokenHolder.fromAccountAddress( + recipient: CborAccountAddress.fromAccountAddress( AccountAddress.fromBase58('4PVJxxtiNVanfuNgvFWtFT1JCiqoVs6npVXBqwLNKprqnUiC2A') ), memo: CborMemo.fromString('Some text for memo'), @@ -95,7 +109,7 @@ value: '200000', decimals: 6, }), - recipient: TokenHolder.fromAccountAddress( + recipient: CborAccountAddress.fromAccountAddress( AccountAddress.fromBase58('4PVJxxtiNVanfuNgvFWtFT1JCiqoVs6npVXBqwLNKprqnUiC2A') ), memo: CborMemo.fromString('Some text for memo'), diff --git a/examples/wallet-api/sponsored-transaction.html b/examples/wallet-api/sponsored-transaction.html new file mode 100644 index 000000000..15cdd4a2a --- /dev/null +++ b/examples/wallet-api/sponsored-transaction.html @@ -0,0 +1,162 @@ + + + + My cool dapp + + + + + + + + +
+ +

Account address:

+
+
+ +
+

Sponsor Config:

+ Sponsor Account: + +
+ Sponsor Private Key: + +
+

Recipient Config:

+ Recipient Address: + +
+
+ + + + diff --git a/packages/browser-wallet-api-helpers/package.json b/packages/browser-wallet-api-helpers/package.json index e28de5291..0d266a94e 100644 --- a/packages/browser-wallet-api-helpers/package.json +++ b/packages/browser-wallet-api-helpers/package.json @@ -40,7 +40,7 @@ "webpack-cli": "^4.9.2" }, "peerDependencies": { - "@concordium/web-sdk": "10.0.2", + "@concordium/web-sdk": "^12.0.0", "@protobuf-ts/runtime-rpc": "^2.9.1" }, "scripts": { diff --git a/packages/browser-wallet-api-helpers/src/wallet-api-types.ts b/packages/browser-wallet-api-helpers/src/wallet-api-types.ts index 7fb636320..65923eb9a 100644 --- a/packages/browser-wallet-api-helpers/src/wallet-api-types.ts +++ b/packages/browser-wallet-api-helpers/src/wallet-api-types.ts @@ -1,30 +1,31 @@ import type { - AccountTransactionPayload, + AccountAddress, + AccountTransactionInput, AccountTransactionSignature, AccountTransactionType, - InitContractPayload, - SchemaVersion, - UpdateContractPayload, - IdStatement, - IdProofOutput, - CredentialStatements, - VerifiablePresentation, - CredentialSubject, - HexString, - AccountAddress, Base58String, Base64String, - ContractAddress, - UpdateCredentialsPayload, - RegisterDataPayload, - SimpleTransferPayload, - SimpleTransferWithMemoPayload, - DeployModulePayload, ConfigureBakerPayload, ConfigureDelegationPayload, + ContractAddress, ContractName, + CredentialStatements, + CredentialSubject, + DeployModulePayload, EntrypointName, + HexString, + IdProofOutput, + IdStatement, + InitContractInput, + RegisterDataPayload, + SchemaVersion, + SimpleTransferPayload, + SimpleTransferWithMemoPayload, TokenUpdatePayload, + UpdateContractInput, + UpdateCredentialsInput, + VerifiablePresentation, + Transaction, } from '@concordium/web-sdk'; import type { RpcTransport } from '@protobuf-ts/runtime-rpc'; import { LaxNumberEnumValue, LaxStringEnumValue } from './util'; @@ -61,14 +62,16 @@ export interface CredentialProof { verificationMethod: string; } -export type SendTransactionUpdateContractPayload = Omit; -export type SendTransactionInitContractPayload = Omit; +export type SendTransactionUpdateContractPayload = Omit; +export type SendTransactionInitContractPayload = Omit; export type SendTransactionPayload = - | Exclude + | Exclude | SendTransactionUpdateContractPayload | SendTransactionInitContractPayload; +export type SignableTransaction = Transaction.Signable; + export type SmartContractParameters = | { [key: string]: SmartContractParameters } | SmartContractParameters[] @@ -168,7 +171,7 @@ interface MainWalletApi { sendTransaction( accountAddress: AccountAddressSource, type: LaxNumberEnumValue, - payload: UpdateCredentialsPayload + payload: UpdateCredentialsInput ): Promise; /** * Sends a transaction to the Concordium Wallet and awaits the users action. Note that a header is not sent, and will be constructed by the wallet itself. @@ -254,6 +257,14 @@ interface MainWalletApi { type: LaxNumberEnumValue, payload: ConfigureDelegationPayload ): Promise; + /** + * Sends a transaction signed by sponsor to the Concordium Wallet and awaits the users action. + * Note that a header is sent, and constructed by the sponsor. + * Note that if the user rejects signing the transaction, this will throw an error. + * @param accountAddress the address of the account that should sign the transaction + * @param transaction the sponsored transaction with header to be signed and sent. + */ + sendSponsoredTransaction(accountAddress: AccountAddressSource, transaction: SignableTransaction): Promise; /** * Sends a message to the Concordium Wallet and awaits the users action. If the user signs the message, this will resolve to the signature. * Note that if the user rejects signing the message, this will throw an error. diff --git a/packages/browser-wallet/CHANGELOG.md b/packages/browser-wallet/CHANGELOG.md index 59f933074..c76a51fc1 100644 --- a/packages/browser-wallet/CHANGELOG.md +++ b/packages/browser-wallet/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- Added support for Sponsored Transactions handling. With new method `sendSponsoredTransaction` in wallet-api. + ## 2.7.0 ### Changed diff --git a/packages/browser-wallet/package.json b/packages/browser-wallet/package.json index 1128c6a40..1b2bfb8e7 100644 --- a/packages/browser-wallet/package.json +++ b/packages/browser-wallet/package.json @@ -22,7 +22,7 @@ "dependencies": { "@concordium/browser-wallet-api-helpers": "workspace:^", "@concordium/common-sdk": "^9.5.3", - "@concordium/web-sdk": "10.0.2", + "@concordium/web-sdk": "^12.0.1", "@floating-ui/react": "^0.27.2", "@noble/ed25519": "^1.7.0", "@protobuf-ts/grpcweb-transport": "^2.9.1", diff --git a/packages/browser-wallet/src/background/credential-deployment.ts b/packages/browser-wallet/src/background/credential-deployment.ts index 9bb9e518e..96c6cfbed 100644 --- a/packages/browser-wallet/src/background/credential-deployment.ts +++ b/packages/browser-wallet/src/background/credential-deployment.ts @@ -1,16 +1,16 @@ import { ExtensionMessageHandler } from '@messaging'; import { - CredentialInput, - getAccountAddress, ConcordiumGRPCWebClient, - createCredentialTransaction, - signCredentialTransaction, ConcordiumHdWallet, - TransactionExpiry, - getCredentialDeploymentTransactionHash, + createCredentialPayload, + CredentialInput, CredentialRegistrationId, + getAccountAddress, + getCredentialDeploymentTransactionHash, serializeCredentialDeploymentPayload, + signCredentialTransaction, + TransactionExpiry, } from '@concordium/web-sdk'; import { GRPCTIMEOUT } from '@shared/constants/networkConfiguration'; import { DEFAULT_TRANSACTION_EXPIRY } from '@shared/constants/time'; @@ -32,7 +32,7 @@ async function createAndSendCredential(credIn: CredentialInput): Promise ({ run: true }), withPromptStart()), + appendUrlToPayload, + undefined, + withPromptEnd +); forwardToPopup( MessageType.SignMessage, InternalMessageType.SignMessage, diff --git a/packages/browser-wallet/src/messaging/message.ts b/packages/browser-wallet/src/messaging/message.ts index b06f5d18d..f94e303e5 100644 --- a/packages/browser-wallet/src/messaging/message.ts +++ b/packages/browser-wallet/src/messaging/message.ts @@ -7,6 +7,7 @@ import { v4 as uuidv4 } from 'uuid'; */ export enum MessageType { SendTransaction = 'M_SendTransaction', + SendSponsoredTransaction = 'M_SendSponsoredTransaction', SignMessage = 'M_SignMessage', GetAccounts = 'M_GetAccounts', GetSelectedAccount = 'M_GetSelectedAccount', @@ -29,6 +30,7 @@ export enum InternalMessageType { Init = 'I_Init', PopupReady = 'I_PopupReady', SendTransaction = 'I_SendTransaction', + SendSponsoredTransaction = 'I_SendSponsoredTransaction', SignMessage = 'I_SignMessage', Connect = 'I_Connect', TestPopupOpen = 'I_TestPopupOpen', diff --git a/packages/browser-wallet/src/popup/constants/routes.ts b/packages/browser-wallet/src/popup/constants/routes.ts index 2a52f5335..47cdaf4aa 100644 --- a/packages/browser-wallet/src/popup/constants/routes.ts +++ b/packages/browser-wallet/src/popup/constants/routes.ts @@ -6,6 +6,8 @@ type RouteChildren = { [key: string]: RouteNode | RoutePath; }; +// ToDo sendSponsoredTransaction not implemented in OldUI +// Need redirect to new UI, or Sunset OldUI export const relativeRoutes = { home: { path: '/', @@ -63,6 +65,9 @@ export const relativeRoutes = { sendTransaction: { path: 'send-transaction', }, + sendSponsoredTransaction: { + path: 'send-sponsored-transaction', + }, endIdentityIssuance: { path: 'end-identity-issuance', }, diff --git a/packages/browser-wallet/src/popup/pages/Account/AccountTransactionFlow/AccountTransactionFlow.tsx b/packages/browser-wallet/src/popup/pages/Account/AccountTransactionFlow/AccountTransactionFlow.tsx index 5fea72bae..c42fecce3 100644 --- a/packages/browser-wallet/src/popup/pages/Account/AccountTransactionFlow/AccountTransactionFlow.tsx +++ b/packages/browser-wallet/src/popup/pages/Account/AccountTransactionFlow/AccountTransactionFlow.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useState } from 'react'; import BackButton from '@popup/shared/BackButton'; import MultiStepForm, { FormChildren, MultiStepFormProps, OrRenderValues } from '@popup/shared/MultiStepForm'; -import { AccountTransactionPayload, AccountTransactionType } from '@concordium/web-sdk'; +import { AccountTransactionInput, AccountTransactionType } from '@concordium/web-sdk'; import { useLocation, useNavigate } from 'react-router-dom'; import { absoluteRoutes } from '@popup/constants/routes'; import { noOp } from 'wallet-common-helpers'; @@ -18,7 +18,7 @@ interface Props> /** * Function to convert flow values into an account transaction. */ - convert(values: F): AccountTransactionPayload; + convert(values: F): AccountTransactionInput; /** * Function that is triggered if an error is thrown in the done handler. */ @@ -56,7 +56,7 @@ export default function AccountTransactionFlow const handleDone = useCallback( (values: F) => { - let payload: AccountTransactionPayload; + let payload: AccountTransactionInput; try { payload = convert(values); nav(pathname, { replace: true, state: values }); // Override current router entry with stateful version diff --git a/packages/browser-wallet/src/popup/pages/Account/ConfirmGenericTransfer.tsx b/packages/browser-wallet/src/popup/pages/Account/ConfirmGenericTransfer.tsx index 55e3abdc1..f3a9da8c8 100644 --- a/packages/browser-wallet/src/popup/pages/Account/ConfirmGenericTransfer.tsx +++ b/packages/browser-wallet/src/popup/pages/Account/ConfirmGenericTransfer.tsx @@ -1,6 +1,6 @@ import React, { useContext, useMemo } from 'react'; import { - AccountTransactionPayload, + AccountTransactionInput, AccountTransactionType, convertEnergyToMicroCcd, getEnergyCost, @@ -12,7 +12,7 @@ import ConfirmTransfer from './ConfirmTransfer'; import { accountPageContext } from './utils'; export type ConfirmGenericTransferState = { - payload: AccountTransactionPayload; + payload: AccountTransactionInput; type: AccountTransactionType; }; diff --git a/packages/browser-wallet/src/popup/pages/Account/ConfirmTransfer/ConfirmTransfer.tsx b/packages/browser-wallet/src/popup/pages/Account/ConfirmTransfer/ConfirmTransfer.tsx index be111f0e5..3c030c859 100644 --- a/packages/browser-wallet/src/popup/pages/Account/ConfirmTransfer/ConfirmTransfer.tsx +++ b/packages/browser-wallet/src/popup/pages/Account/ConfirmTransfer/ConfirmTransfer.tsx @@ -1,17 +1,17 @@ /* eslint-disable react/destructuring-assignment */ -import React, { useEffect, useState, useMemo } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { useSetAtom, useAtomValue } from 'jotai'; +import { useAtomValue, useSetAtom } from 'jotai'; import { selectedAccountAtom } from '@popup/store/account'; import { AccountAddress, - AccountTransactionPayload, + AccountTransactionInput, AccountTransactionType, - UpdateContractPayload, + UpdateContractInput, } from '@concordium/web-sdk'; import { - getDefaultExpiry, createPendingTransactionFromAccountTransaction, + getDefaultExpiry, sendTransaction, } from '@popup/shared/utils/transaction-helpers'; import { grpcClientAtom } from '@popup/store/settings'; @@ -21,8 +21,8 @@ import Button from '@popup/shared/Button'; import { useNavigate } from 'react-router-dom'; import { absoluteRoutes } from '@popup/constants/routes'; import GenericTransactionReceipt, { - TokenTransferReceipt, GenericTransactionReceiptProps, + TokenTransferReceipt, TokenTransferReceiptProps, } from '@popup/shared/TransactionReceipt'; import { useUpdateAtom } from 'jotai/utils'; @@ -42,14 +42,14 @@ type BaseProps = { type ConfirmTokenTransferProps = BaseProps & { showAsTokenTransfer: true; transactionType: AccountTransactionType.Update; - payload: UpdateContractPayload; + payload: UpdateContractInput; parameters: SmartContractParameters; metadata: TokenMetadata; }; type ConfirmGenericTransferProps = BaseProps & { showAsTokenTransfer?: false; - payload: AccountTransactionPayload; + payload: AccountTransactionInput; transactionType: AccountTransactionType; parameters?: SmartContractParameters; }; diff --git a/packages/browser-wallet/src/popup/pages/Account/Earn/Baking/utils.ts b/packages/browser-wallet/src/popup/pages/Account/Earn/Baking/utils.ts index 1a1bdeeca..187f43acb 100644 --- a/packages/browser-wallet/src/popup/pages/Account/Earn/Baking/utils.ts +++ b/packages/browser-wallet/src/popup/pages/Account/Earn/Baking/utils.ts @@ -1,14 +1,14 @@ import { + AccountBakerDetailsV1, AccountInfo, + AccountInfoBaker, + AccountInfoType, + BakerKeysWithProofs, CcdAmount, CommissionRates, - OpenStatus, ConfigureBakerPayload, + OpenStatus, OpenStatusText, - BakerKeysWithProofs, - AccountInfoType, - AccountInfoBaker, - AccountBakerDetailsV1, } from '@concordium/web-sdk'; import { decimalToRewardFraction, fractionToPercentage } from '@popup/shared/utils/baking-helpers'; import { getConfigureBakerEnergyCost } from '@shared/utils/energy-helpers'; @@ -26,7 +26,7 @@ export type ConfigureBakerFlowState = { keys: BakerKeysWithProofs | null; }; -function openStatusFromText(status: OpenStatusText): OpenStatus { +function openStatusFromText(status: OpenStatusText | null): OpenStatus { switch (status) { case OpenStatusText.ClosedForAll: return OpenStatus.ClosedForAll; diff --git a/packages/browser-wallet/src/popup/pages/Account/Earn/Earn.tsx b/packages/browser-wallet/src/popup/pages/Account/Earn/Earn.tsx index 525718406..7ba983138 100644 --- a/packages/browser-wallet/src/popup/pages/Account/Earn/Earn.tsx +++ b/packages/browser-wallet/src/popup/pages/Account/Earn/Earn.tsx @@ -24,7 +24,7 @@ import { useBlockChainParametersAboveV0 } from '@popup/shared/BlockChainParamete import Baking from './Baking'; import Delegate from './Delegate'; import { accountPageContext } from '../utils'; -import { filterType, EarnPageContext, earnPageContext } from './utils'; +import { EarnPageContext, earnPageContext, filterType } from './utils'; import { accountRoutes } from '../routes'; const routes = { @@ -73,7 +73,9 @@ function Earn({ chainParameters }: EarnProps) { ); } -function isNotRewardStatusV0(rewardStatus?: RewardStatus): rewardStatus is Exclude { +function isNotRewardStatusV0( + rewardStatus?: RewardStatus | null +): rewardStatus is Exclude { return rewardStatus ? rewardStatus.version !== 0 : false; } diff --git a/packages/browser-wallet/src/popup/pages/Account/SendCcd/ConfirmTokenTransfer.tsx b/packages/browser-wallet/src/popup/pages/Account/SendCcd/ConfirmTokenTransfer.tsx index bdf639f29..74029e75a 100644 --- a/packages/browser-wallet/src/popup/pages/Account/SendCcd/ConfirmTokenTransfer.tsx +++ b/packages/browser-wallet/src/popup/pages/Account/SendCcd/ConfirmTokenTransfer.tsx @@ -1,8 +1,8 @@ import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import { useSetAtom, useAtomValue } from 'jotai'; +import { useAtomValue, useSetAtom } from 'jotai'; import { selectedAccountAtom } from '@popup/store/account'; -import { AccountTransactionType, UpdateContractPayload } from '@concordium/web-sdk'; +import { AccountTransactionType, UpdateContractInput } from '@concordium/web-sdk'; import { grpcClientAtom } from '@popup/store/settings'; import { addToastAtom } from '@popup/state'; import { useLocation } from 'react-router-dom'; @@ -30,7 +30,7 @@ export default function ConfirmTokenTransfer({ setDetailsExpanded, cost }: Props [] ); - const payload: UpdateContractPayload | undefined = useMemo(() => { + const payload: UpdateContractInput | undefined = useMemo(() => { if (!parameters || !contractName) { return undefined; } diff --git a/packages/browser-wallet/src/popup/popupX/constants/routes.ts b/packages/browser-wallet/src/popup/popupX/constants/routes.ts index 6d55e07f6..b1f5b37b7 100644 --- a/packages/browser-wallet/src/popup/popupX/constants/routes.ts +++ b/packages/browser-wallet/src/popup/popupX/constants/routes.ts @@ -410,6 +410,9 @@ export const relativeRoutes = { sendTransaction: { path: 'sendTransaction', }, + sendSponsoredTransaction: { + path: 'sendSponsoredTransaction', + }, addWeb3IdCredential: { path: 'add-web3id-credential', }, diff --git a/packages/browser-wallet/src/popup/popupX/pages/EarningRewards/Validator/TransactionFlow.tsx b/packages/browser-wallet/src/popup/popupX/pages/EarningRewards/Validator/TransactionFlow.tsx index 345984b7b..cbfb2cc92 100644 --- a/packages/browser-wallet/src/popup/popupX/pages/EarningRewards/Validator/TransactionFlow.tsx +++ b/packages/browser-wallet/src/popup/popupX/pages/EarningRewards/Validator/TransactionFlow.tsx @@ -14,7 +14,7 @@ import { useSelectedAccountInfo } from '@popup/shared/AccountInfoListenerContext import { formatCcdAmount } from '@popup/popupX/shared/utils/helpers'; import Text from '@popup/popupX/shared/Text'; -import { ValidatorForm, ValidatorFormExisting, configureValidatorFromForm } from './util'; +import { configureValidatorFromForm, ValidatorForm, ValidatorFormExisting } from './util'; import ValidatorStake from './Stake'; import { type ValidationResultLocationState } from './Result'; import OpenPool from './OpenPool'; @@ -136,6 +136,10 @@ function withChangeValidation(Flow: ComponentType) { accountBaker: { stakedAmount, restakeEarnings, bakerPoolInfo }, } = accountInfo; + if (bakerPoolInfo.openStatus === null) { + return null; + } + const existing: ValidatorFormExisting = { stake: { amount: formatCcdAmount(stakedAmount), diff --git a/packages/browser-wallet/src/popup/popupX/pages/EarningRewards/Validator/util.ts b/packages/browser-wallet/src/popup/popupX/pages/EarningRewards/Validator/util.ts index 9a923840b..5bb9ba9e4 100644 --- a/packages/browser-wallet/src/popup/popupX/pages/EarningRewards/Validator/util.ts +++ b/packages/browser-wallet/src/popup/popupX/pages/EarningRewards/Validator/util.ts @@ -17,7 +17,7 @@ export function showValidatorAmount(amount: CcdAmount.Type): string { return `${formatCcdAmount(amount)} CCD`; } -export function showValidatorOpenStatus(status: OpenStatusText | OpenStatus): string { +export function showValidatorOpenStatus(status: OpenStatusText | OpenStatus | null): string { switch (status) { case OpenStatus.OpenForAll: case OpenStatusText.OpenForAll: diff --git a/packages/browser-wallet/src/popup/popupX/pages/SendFunds/Confirm.tsx b/packages/browser-wallet/src/popup/popupX/pages/SendFunds/Confirm.tsx index cde31dccd..6d14ebd05 100644 --- a/packages/browser-wallet/src/popup/popupX/pages/SendFunds/Confirm.tsx +++ b/packages/browser-wallet/src/popup/popupX/pages/SendFunds/Confirm.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import { Cbor, CborMemo, TokenAmount, TokenId, TokenOperationType, TokenHolder } from '@concordium/web-sdk/plt'; +import { Cbor, CborMemo, TokenAmount, TokenId, TokenOperationType, CborAccountAddress } from '@concordium/web-sdk/plt'; import { AccountAddress, AccountTransactionType, @@ -116,7 +116,7 @@ export default function SendFundsConfirm({ values, fee, sender }: Props) { value: parseTokenAmount(values.amount, tokenMetadata?.decimals).toString(), decimals: tokenMetadata?.decimals || 0, }), - recipient: TokenHolder.fromAccountAddress(receiver), + recipient: CborAccountAddress.fromAccountAddress(receiver), memo: values.memo ? CborMemo.fromString(values.memo) : undefined, }, }, diff --git a/packages/browser-wallet/src/popup/popupX/pages/SendFunds/SendFunds.tsx b/packages/browser-wallet/src/popup/popupX/pages/SendFunds/SendFunds.tsx index 9b4906454..8faa3e46c 100644 --- a/packages/browser-wallet/src/popup/popupX/pages/SendFunds/SendFunds.tsx +++ b/packages/browser-wallet/src/popup/popupX/pages/SendFunds/SendFunds.tsx @@ -18,7 +18,7 @@ import { TokenId, TokenAmount as TokenAmountPlt, TokenOperationType, - TokenHolder, + CborAccountAddress, } from '@concordium/web-sdk/plt'; import { useAsyncMemo } from 'wallet-common-helpers'; import { useAtomValue } from 'jotai'; @@ -104,7 +104,7 @@ function SendFunds({ address }: SendFundsProps) { value: parseTokenAmount(amount, metadata?.decimals).toString(), decimals: metadata?.decimals || 0, }), - recipient: TokenHolder.fromAccountAddress(address), + recipient: CborAccountAddress.fromAccountAddress(address), memo: memo ? CborMemo.fromString(memo) : undefined, }, }, diff --git a/packages/browser-wallet/src/popup/popupX/pages/SubmittedTransaction/SubmittedTransaction.tsx b/packages/browser-wallet/src/popup/popupX/pages/SubmittedTransaction/SubmittedTransaction.tsx index d2d9e67aa..ad9b259ab 100644 --- a/packages/browser-wallet/src/popup/popupX/pages/SubmittedTransaction/SubmittedTransaction.tsx +++ b/packages/browser-wallet/src/popup/popupX/pages/SubmittedTransaction/SubmittedTransaction.tsx @@ -10,21 +10,21 @@ import { absoluteRoutes, transactionDetailsRoute } from '@popup/popupX/constants import Card from '@popup/popupX/shared/Card'; import { useAsyncMemo } from 'wallet-common-helpers'; import { + AccountTransactionPayload, AccountTransactionSummary, + AccountTransactionType, + BaseAccountTransactionSummary, + CcdAmount, + ConfigureBakerPayload, + ConfigureDelegationPayload, + FailedTransactionSummary, HexString, - TransactionHash, - TransactionSummaryType, isRejectTransaction, isSuccessTransaction, - FailedTransactionSummary, - BaseAccountTransactionSummary, - AccountTransactionPayload, - AccountTransactionType, SimpleTransferPayload, SimpleTransferWithMemoPayload, - ConfigureBakerPayload, - ConfigureDelegationPayload, - CcdAmount, + TransactionHash, + TransactionSummaryType, } from '@concordium/web-sdk'; import { useAtomValue } from 'jotai'; import { grpcClientAtom } from '@popup/store/settings'; @@ -284,6 +284,9 @@ export default function SubmittedTransaction() { TX_TIMEOUT ); + if (!outcome.summary) { + throw Error('Unexpected transaction type'); + } if (isRejectTransaction(outcome.summary)) { return { type: 'failure', summary: outcome.summary }; } diff --git a/packages/browser-wallet/src/popup/popupX/pages/prompts/SendSponsoredTransaction/DisplaySingleTransferTokenUpdate.tsx b/packages/browser-wallet/src/popup/popupX/pages/prompts/SendSponsoredTransaction/DisplaySingleTransferTokenUpdate.tsx new file mode 100644 index 000000000..af4eb9e30 --- /dev/null +++ b/packages/browser-wallet/src/popup/popupX/pages/prompts/SendSponsoredTransaction/DisplaySingleTransferTokenUpdate.tsx @@ -0,0 +1,346 @@ +import React, { useContext, useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { + AccountInfo, + HexString, + isRejectTransaction, + isSuccessTransaction, + TokenUpdatePayload, + TransactionHash, + TransactionSummaryType, +} from '@concordium/web-sdk'; +import { Cbor, CborMemo, TokenOperationType, TokenTransferOperation } from '@concordium/web-sdk/plt'; +import { WalletCredential } from '@shared/storage/types'; +import { displaySplitAddress, useCredential, useIdentityName } from '@popup/shared/utils/account-helpers'; +import { useAccountInfo } from '@popup/shared/AccountInfoListenerContext'; +import { formatTokenAmount } from '@popup/popupX/shared/utils/helpers'; +import { displayUrl } from '@popup/shared/utils/string-helpers'; +import { logError } from '@shared/utils/log-helpers'; +import { LoaderInline } from '@popup/popupX/shared/Loader'; +import { fullscreenPromptContext } from '@popup/popupX/page-layouts/FullscreenPromptLayout'; +import { useAtomValue, useSetAtom } from 'jotai'; +import { addToastAtom } from '@popup/state'; +import { grpcClientAtom } from '@popup/store/settings'; +import { useAsyncMemo } from 'wallet-common-helpers'; +import Page from '@popup/popupX/shared/Page'; +import Text from '@popup/popupX/shared/Text'; +import Card from '@popup/popupX/shared/Card'; +import Button from '@popup/popupX/shared/Button'; +import Label from '@popup/popupX/shared/Label'; +import Tooltip from '@popup/popupX/shared/Tooltip/Tooltip'; +import QuestionIcon from '@assets/svgX/UiKit/Interface/circled-question-mark.svg'; +import CheckCircle from '@assets/svgX/check-circle.svg'; +import Cross from '@assets/svgX/close.svg'; + +interface Status { + type?: 'success' | 'failure'; +} + +function TransactionStatusIcon({ status }: { status?: Status }) { + const { t } = useTranslation('x', { keyPrefix: 'prompts.sendTransactionX.sponsored' }); + switch (status?.type) { + case undefined: { + return ( + <> + + {t('pending.label')} + + ); + } + case 'success': { + return ( + <> + + {t('success.label')} + + ); + } + case 'failure': { + return ( + <> + + {t('failure.label')} + + ); + } + default: + throw new Error('Unexpected status'); + } +} + +type TransactionStatusProps = { + status?: Status; + amount?: string | number; + sponsorAccount?: string; + tokenName?: string; +}; + +function TransactionStatus({ status, amount, sponsorAccount, tokenName }: TransactionStatusProps) { + const { t } = useTranslation('x', { keyPrefix: 'prompts.sendTransactionX.sponsored' }); + + return ( + <> + + {t('tokenNameAmount', { tokenName })} + {amount} + {t('transactionFee')}: +