上次的交互是只读的,现在我们通过发送交易来与合约交互。 我们在合约上开发的第一个功能是递增。让我们在主页面上添加一个发送交易的按钮。正如您所记得的,在链上发送交易需要花费GAS,因此我们希望钱包能与用户一起批准这一操作,并显示将花费多少Ton币。 在开始之前,我们将添加另一个钩子,从 TON Connect 接口生成一个发送方对象。该发送方代表已连接的钱包,允许我们代表它们发送交易。 在处理该交易请求时,我们还将在用户界面中显示钱包的连接状态,以便我们的用户界面将隐藏需要授权的元素。 就像我们在之前的课程中所做的那样,让我们使用 React 钩子来保留一些我们稍后将在代码中使用的功能。 让我们创建包含以下内容的文件 src/hooks/useTonConnect.ts: - import { useTonConnectUI } from '@tonconnect/ui-react';
0 S1 \+ r6 @! a$ c - import { Sender, SenderArguments } from 'ton-core';
! o+ ?2 l, ?/ v+ |3 v' O
2 f, ~8 E9 U1 v. {* Q9 i2 o2 L- export function useTonConnect(): { sender: Sender; connected: boolean } {
, X) A$ N$ G* ] A% x. C" u - const [tonConnectUI] = useTonConnectUI();$ f6 R6 `7 r6 [3 |9 ?
- 6 z2 u) C* s$ O3 x! O, c+ q: `
- return {
. h9 h9 v# b, |' A - sender: {
/ P* \ Y0 i; V% o2 j; Z5 Q0 Y9 N - send: async (args: SenderArguments) => {7 z' q6 Y8 o. r- A
- tonConnectUI.sendTransaction({2 i# ~% ]1 b: p- S5 k
- messages: [
5 Z3 u/ ] U2 q6 Q" a4 D* s( k% U - {
! b7 _; p. \, Q" @8 q0 X! S# ?5 ~ F - address: args.to.toString(),
! R8 r) `( T! ~! v0 I U. D# R* ?- T - amount: args.value.toString(),4 F5 u5 e6 O! p9 y$ U, o. i
- payload: args.body?.toBoc().toString('base64')," ]3 n! }+ ]0 i, S
- },
" k# H, T- G w; e - ],
- v9 g% b$ g& m; m$ T - validUntil: Date.now() + 5 * 60 * 1000, // 5 minutes for user to approve( a4 q* e! j6 R) M) d
- });
1 i* u7 b7 H' R/ | - },+ U q/ c0 V4 V k, {7 e. v
- },7 k, _' ~. ^" A3 Q
- connected: tonConnectUI.connected,% F! B, v( t3 }, W1 Q
- };( W m+ D% e9 @7 h
- }
复制代码您可以看到,我们正在返回一个对象,其中的函数 send 可以让我们触发交易请求,参数 connected 可以存储连接的当前状态。 接下来我们要做的是优化现有的 useCounterContract 钩子,并添加两个小功能。 我们需要更新一些代码: - // ... previous imports9 R c; w* }; }) O( D8 e
- import { toNano } from "ton-core";
( ^& O, E+ m, S* |; L - import { useTonConnect } from "./useTonConnect";& c. N% N# _% B/ h2 {( b; f
; s5 O( r! Z, y# L* v4 b; i- , d e* i' \4 v4 K# @6 T
- export function useCounterContract() {7 G- D; z8 j; K1 o3 p3 @
/ k/ o; _$ ?' Z- // ... variables definitions# Q2 A+ J1 d" h$ D7 h
- const { sender } = useTonConnect();
) F3 j; q5 ^1 C; x - 7 {, {6 [ p+ [
- const sleep = (time: number) => new Promise((resolve) => setTimeout(resolve, time));
5 y8 c/ T; y9 w) ~, r+ w - ! Q/ k) @; R+ o1 B; u* O h! p
- // ... mainContract definition
8 @+ {: s) S, o; C3 {7 C7 ] - 4 w* Q6 w- d% M8 \
- useEffect(() => {- j# c; b0 ]# w& l4 {" s
- async function getValue() {; N8 P+ T+ W$ X1 }
- + v+ F9 M) y8 L A
- // ... previous getValue code
8 X$ @1 D; A, A: ~2 Y - 6 U2 C; g" `7 q/ g( T& j- u B" Y
- await sleep(5000); // sleep 5 seconds and poll value again
+ N) o5 L" _1 v6 x: |- A: `: f' S+ } - getValue();
+ K- S1 N) g" r6 m - }
! p# N( {9 I3 L9 N4 x - getValue();" |) R$ G0 I" C2 x1 `
- }, [counterContract]);
. ]' F* C5 l: V - 0 M3 a1 H3 Q- G2 }2 }+ Y. n7 M
- 3 ]% W: H$ F6 S+ F d- f# x! U
- return {
3 m8 [! z0 m$ D4 W - value: val,
0 G2 j5 q3 @4 u/ A' `8 X - address: counterContract?.address.toString(),
. Q; _% I8 k8 k- S& p6 o - sendIncrement: () => {
2 e) J. k e/ }% ?% i - return mainContract?.sendIncrement(sender, toNano(0.05), 3);
& g( R3 P7 V/ k& V* E - },
" R/ ]& a. p" u% w8 i. r4 e! u - };/ N# I# X8 ~ ~' E8 `. ]
- }
复制代码此时,我们只需更新用户界面,就可以触发所需的交易。我们还需要在其中添加两样东西:
X, k/ o; j) A- // ... previous imports! y3 n) z2 m* I. @9 |2 X
- import { useTonConnect } from "./hooks/useTonConnect";& G9 k8 J8 N9 h) H E
1 ^- [- m" j9 x- y" B4 u3 J; a8 G
0 s" g) H$ \1 M3 e- L- function App() {
* J6 G9 g6 C8 |+ ]8 q/ g. M/ { -
; }0 q+ C+ H: o0 J9 u* y - const { ..., sendIncrement } = useMainContract();
" s. v$ c% h* J: `- l - const { connected } = useTonConnect()
# H0 f p N6 O$ l l# A -
L8 }. d e' i7 J - return (
3 H+ E9 x7 b* p4 ~) ? - // ... other HTML code, y( b3 \/ o! k% P& i, }* Y8 f9 ^
- : ?* j( _4 X) g9 `6 g& F0 W8 K/ n+ D' i
- {connected && (
. P& c. p, B$ ^: |0 e" f! r- y - <a* [- E/ P# w5 L
- onClick={() => {6 E- G R9 l" s# x1 z
- sendIncrement();
]0 J2 Q7 S; _- [& L! d - }}, K1 W/ H8 ]6 H: g
- >1 ^( b# E3 s/ k d
- Increment
" Q5 Q8 w' J2 a, c - </a>: Y w7 l0 f" r9 |
- )}! l6 A) Q" R" M G1 i
- 4 y; g: }! d4 x+ @ }
- // ... other HTML code
8 y1 f6 C; S" O3 _ - )
" |& `% g* w( x - }
复制代码
1 O' A: b4 u! r+ t3 u& a
S7 k r* q" a8 ]7 o" ]4 ]8 y# g& Z) W
|