Skip to content

Commit 1a1c3b7

Browse files
authored
refactor: sui transactions to be send as base64 encoded BCS instead of json (#899)
1 parent d809930 commit 1a1c3b7

File tree

6 files changed

+52
-25
lines changed

6 files changed

+52
-25
lines changed

advanced/dapps/react-dapp-v2/src/contexts/JsonRpcContext.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ export function JsonRpcContextProvider({
572572
// check the session.sessionProperties first for capabilities
573573
const capabilitiesJson = session?.sessionProperties?.["capabilities"];
574574
const walletCapabilities =
575-
capabilitiesJson && JSON.parse(capabilitiesJson);
575+
capabilitiesJson && JSON.parse(capabilitiesJson as string);
576576
let capabilities = walletCapabilities[address] as
577577
| GetCapabilitiesResult
578578
| undefined;
@@ -2142,7 +2142,7 @@ export function JsonRpcContextProvider({
21422142
let result;
21432143
if (addresses) {
21442144
console.log("cached addresses", addresses);
2145-
const parsed = JSON.parse(addresses);
2145+
const parsed = JSON.parse(addresses as string);
21462146
result = isOrdinal ? parsed.ordinal : parsed.payment;
21472147
console.log("parsed", result);
21482148
} else {
@@ -2285,12 +2285,15 @@ export function JsonRpcContextProvider({
22852285
tx.setSender(address);
22862286
tx.transferObjects([coin], recipient?.trim() || address);
22872287

2288-
const serialized = await tx.toJSON();
2288+
const suiClient = getSuiClient(chainId);
2289+
const bcsTransaction = await tx.build({ client: suiClient });
2290+
22892291
const req = {
2290-
transaction: Buffer.from(serialized).toString("base64"),
2292+
transaction: Buffer.from(bcsTransaction).toString("base64"),
22912293
address,
22922294
};
2293-
console.log("req", req, serialized);
2295+
2296+
console.log("req", req, Buffer.from(bcsTransaction).toString("base64"));
22942297
const result = await client!.request<{ digest: string }>({
22952298
topic: session!.topic,
22962299
chainId: chainId,
@@ -2323,12 +2326,16 @@ export function JsonRpcContextProvider({
23232326

23242327
tx.transferObjects([coin], address);
23252328

2326-
const serialized = await tx.toJSON();
2329+
const suiClient = getSuiClient(chainId);
2330+
2331+
const bcsTransaction = await tx.build({ client: suiClient });
2332+
23272333
const req = {
2328-
transaction: Buffer.from(serialized).toString("base64"),
2334+
transaction: Buffer.from(bcsTransaction).toString("base64"),
23292335
address,
23302336
};
2331-
console.log("req", req, serialized);
2337+
2338+
console.log("req", req, Buffer.from(bcsTransaction).toString("base64"));
23322339
const result = await client!.request<{
23332340
signature: string;
23342341
transactionBytes: string;

advanced/dapps/react-dapp-v2/src/helpers/sui.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import { SuiClient } from "@mysten/sui/client";
33
// Cache clients
44
const clients = new Map<string, SuiClient>();
55

6-
export async function getSuiClient(chainId: string) {
6+
export function getSuiClient(chainId: string): SuiClient {
77
if (clients.has(chainId)) {
8-
return clients.get(chainId);
8+
return clients.get(chainId)!;
99
}
1010
let client: SuiClient;
1111
switch (chainId) {

advanced/dapps/react-dapp-v2/src/pages/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,8 @@ const Home: NextPage = () => {
237237
let availableActions: AccountAction[] = [];
238238
const chainIdAsHex = `0x${numberToHex(parseInt(chainId))}`;
239239
const capabilitiesJson = session?.sessionProperties?.["capabilities"];
240-
const walletCapabilities = capabilitiesJson && JSON.parse(capabilitiesJson);
240+
const walletCapabilities =
241+
capabilitiesJson && JSON.parse(capabilitiesJson as string);
241242
session?.namespaces?.["eip155"].methods.forEach((methodName) => {
242243
const action: AccountAction | undefined =
243244
actions[methodName as keyof typeof actions];

advanced/wallets/react-wallet-v2/src/lib/SuiLib.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export default class SuiLib {
7676
}
7777

7878
public async signTransaction({ transaction, chainId }: ISignTransactionArguments) {
79-
const tx = Transaction.from(Buffer.from(transaction, 'base64').toString('utf8'))
79+
const tx = Transaction.from(transaction)
8080
const client = this.getSuiClient(chainId)
8181
console.log('tx', tx)
8282
const signature = await tx.sign({ signer: this.keypair, client })
@@ -93,7 +93,7 @@ export default class SuiLib {
9393
transaction,
9494
chainId
9595
}: ISignAndExecuteTransactionArguments) {
96-
const tx = Transaction.from(Buffer.from(transaction, 'base64').toString('utf8'))
96+
const tx = Transaction.from(transaction)
9797
const client = this.getSuiClient(chainId)
9898
const executor = new SerialTransactionExecutor({ signer: this.keypair, client })
9999
const result = await executor.executeTransaction(tx)
@@ -121,4 +121,15 @@ export default class SuiLib {
121121
}
122122
return this.suiClients[chainId]
123123
}
124+
125+
public async getJsonTransactionFromBase64(transaction: string) {
126+
try {
127+
const tx = Transaction.from(transaction)
128+
const jsonTx = await tx.toJSON()
129+
return jsonTx
130+
} catch (e) {
131+
console.error('Error decoding transaction', e)
132+
return undefined
133+
}
134+
}
124135
}

advanced/wallets/react-wallet-v2/src/views/SessionSignAndExecuteSuiTransactionModal.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
/* eslint-disable react-hooks/rules-of-hooks */
22
import { Col, Divider, Row, Text } from '@nextui-org/react'
3-
import { useCallback, useState } from 'react'
3+
import { useCallback, useMemo, useState } from 'react'
44

55
import RequesDetailsCard from '@/components/RequestDetalilsCard'
66
import ModalStore from '@/store/ModalStore'
77
import { approveEIP155Request, rejectEIP155Request } from '@/utils/EIP155RequestHandlerUtil'
88
import { styledToast } from '@/utils/HelperUtil'
99
import { walletkit } from '@/utils/WalletConnectUtil'
1010
import RequestModal from '../components/RequestModal'
11-
import { suiAddresses } from '@/utils/SuiWalletUtil'
11+
import { getWallet, suiAddresses } from '@/utils/SuiWalletUtil'
1212
import { approveSuiRequest, rejectSuiRequest } from '@/utils/SuiRequestHandlerUtil'
1313

1414
export default function SessionSignSuiAndExecuteTransactionModal() {
@@ -17,6 +17,7 @@ export default function SessionSignSuiAndExecuteTransactionModal() {
1717
const requestSession = ModalStore.state.data?.requestSession
1818
const [isLoadingApprove, setIsLoadingApprove] = useState(false)
1919
const [isLoadingReject, setIsLoadingReject] = useState(false)
20+
const [transaction, setTransaction] = useState<string | undefined>(undefined)
2021

2122
// Ensure request and wallet are defined
2223
if (!requestEvent || !requestSession) {
@@ -27,10 +28,13 @@ export default function SessionSignSuiAndExecuteTransactionModal() {
2728
const { topic, params } = requestEvent
2829
const { request, chainId } = params
2930

30-
// Get message, convert it to UTF8 string if it is valid hex
31-
const transaction = request.params?.transaction
32-
? Buffer.from(request.params.transaction, 'base64').toString('utf8')
33-
: ''
31+
// transaction is a base64 encoded BCS transaction
32+
useMemo(async () => {
33+
if (transaction) return
34+
const wallet = await getWallet()
35+
const jsonTx = await wallet.getJsonTransactionFromBase64(request.params.transaction)
36+
setTransaction(jsonTx?.toString())
37+
}, [request.params, transaction])
3438

3539
// Handle approve action (logic varies based on request method)
3640
const onApprove = useCallback(async () => {

advanced/wallets/react-wallet-v2/src/views/SessionSignSuiTransactionModal.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
/* eslint-disable react-hooks/rules-of-hooks */
22
import { Col, Divider, Row, Text } from '@nextui-org/react'
3-
import { useCallback, useState } from 'react'
3+
import { useCallback, useMemo, useState } from 'react'
44

55
import RequesDetailsCard from '@/components/RequestDetalilsCard'
66
import ModalStore from '@/store/ModalStore'
77
import { styledToast } from '@/utils/HelperUtil'
88
import { walletkit } from '@/utils/WalletConnectUtil'
99
import RequestModal from '../components/RequestModal'
10-
import { suiAddresses } from '@/utils/SuiWalletUtil'
10+
import { suiAddresses, getWallet } from '@/utils/SuiWalletUtil'
1111
import { approveSuiRequest, rejectSuiRequest } from '@/utils/SuiRequestHandlerUtil'
1212

1313
export default function SessionSignSuiTransactionModal() {
1414
// Get request and wallet data from store
1515
const requestEvent = ModalStore.state.data?.requestEvent
1616
const requestSession = ModalStore.state.data?.requestSession
17+
const [transaction, setTransaction] = useState<string | undefined>(undefined)
1718
const [isLoadingApprove, setIsLoadingApprove] = useState(false)
1819
const [isLoadingReject, setIsLoadingReject] = useState(false)
1920

@@ -26,10 +27,13 @@ export default function SessionSignSuiTransactionModal() {
2627
const { topic, params } = requestEvent
2728
const { request, chainId } = params
2829

29-
// Get message, convert it to UTF8 string if it is valid hex
30-
const transaction = request.params?.transaction
31-
? Buffer.from(request.params.transaction, 'base64').toString('utf8')
32-
: ''
30+
// transaction is a base64 encoded BCS transaction
31+
useMemo(async () => {
32+
if (transaction) return
33+
const wallet = await getWallet()
34+
const jsonTx = await wallet.getJsonTransactionFromBase64(request.params.transaction)
35+
setTransaction(jsonTx?.toString())
36+
}, [request.params, transaction])
3337

3438
// Handle approve action (logic varies based on request method)
3539
const onApprove = useCallback(async () => {

0 commit comments

Comments
 (0)