5
5
ConnectionProvider ,
6
6
WalletProvider ,
7
7
useAnchorWallet ,
8
+ useConnection ,
8
9
} from "@solana/wallet-adapter-react" ;
9
10
import {
10
11
WalletDisconnectButton ,
@@ -20,20 +21,31 @@ import * as buffer from "buffer";
20
21
import { AnchorProvider , BN , Program , Wallet } from "@coral-xyz/anchor" ;
21
22
import { SendUSDApp , IDL } from "./idl/send_usd_app" ;
22
23
import { PriceServiceConnection } from "@pythnetwork/price-service-client" ;
24
+ import { useState } from "react" ;
23
25
window . Buffer = buffer . Buffer ;
24
26
25
27
require ( "@solana/wallet-adapter-react-ui/styles.css" ) ;
26
28
27
29
const SOL_PRICE_FEED_ID =
28
30
"0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d" ;
29
- async function postPriceUpdate ( connection : Connection , wallet ?: AnchorWallet ) {
30
- if ( wallet === undefined ) {
31
+ const SEND_USD_PROGRAM_ID : PublicKey = new PublicKey (
32
+ "2e5gZD3suxgJgkCg4pkoogxDKszy1SAwokz8mNeZUj4M"
33
+ ) ;
34
+ const HERMES_URL = "https://hermes.pyth.network/" ;
35
+ const DEVNET_RPC_URL = "https://api.devnet.solana.com" ;
36
+
37
+ async function postPriceUpdate (
38
+ connection : Connection ,
39
+ wallet : AnchorWallet | undefined ,
40
+ destination : PublicKey | undefined ,
41
+ amount : number | undefined
42
+ ) {
43
+ if ( ! ( wallet && destination && amount ) ) {
31
44
return ;
32
45
} else {
33
- const priceServiceConnection = new PriceServiceConnection (
34
- "https://hermes.pyth.network/" ,
35
- { priceFeedRequestConfig : { binary : true } }
36
- ) ;
46
+ const priceServiceConnection = new PriceServiceConnection ( HERMES_URL , {
47
+ priceFeedRequestConfig : { binary : true } ,
48
+ } ) ;
37
49
const pythSolanaReceiver = new PythSolanaReceiver ( {
38
50
connection,
39
51
wallet : wallet as Wallet ,
@@ -45,12 +57,12 @@ async function postPriceUpdate(connection: Connection, wallet?: AnchorWallet) {
45
57
46
58
const sendUsdApp = new Program < SendUSDApp > (
47
59
IDL as SendUSDApp ,
48
- new PublicKey ( "2e5gZD3suxgJgkCg4pkoogxDKszy1SAwokz8mNeZUj4M" ) ,
49
- new AnchorProvider ( connection , wallet , { commitment : "processed" } )
60
+ SEND_USD_PROGRAM_ID ,
61
+ new AnchorProvider ( connection , wallet , AnchorProvider . defaultOptions ( ) )
50
62
) ;
51
63
52
64
const transactionBuilder = pythSolanaReceiver . newTransactionBuilder ( {
53
- closeUpdateAccounts : false ,
65
+ closeUpdateAccounts : true ,
54
66
} ) ;
55
67
await transactionBuilder . addPostPriceUpdates ( [ priceUpdateData [ 0 ] ] ) ;
56
68
@@ -61,11 +73,9 @@ async function postPriceUpdate(connection: Connection, wallet?: AnchorWallet) {
61
73
return [
62
74
{
63
75
instruction : await sendUsdApp . methods
64
- . send ( new BN ( 1 ) )
76
+ . send ( new BN ( amount ) )
65
77
. accounts ( {
66
- destination : new PublicKey (
67
- "BTwXQZS3EzfxBkv2A54estmn9YbmcpmRWeFP4f3avLi4"
68
- ) ,
78
+ destination,
69
79
priceUpdate : getPriceUpdateAccount ( SOL_PRICE_FEED_ID ) ,
70
80
} )
71
81
. instruction ( ) ,
@@ -84,14 +94,22 @@ async function postPriceUpdate(connection: Connection, wallet?: AnchorWallet) {
84
94
}
85
95
}
86
96
87
- function Button ( ) {
88
- const connection = new Connection ( "https://api.devnet.solana.com" ) ;
97
+ function Button ( props : {
98
+ destination : PublicKey | undefined ;
99
+ amount : number | undefined ;
100
+ } ) {
101
+ const connectionContext = useConnection ( ) ;
89
102
const wallet = useAnchorWallet ( ) ;
90
103
91
104
return (
92
105
< button
93
106
onClick = { async ( ) => {
94
- await postPriceUpdate ( connection , wallet ) ;
107
+ await postPriceUpdate (
108
+ connectionContext . connection ,
109
+ wallet ,
110
+ props . destination ,
111
+ props . amount
112
+ ) ;
95
113
} }
96
114
>
97
115
Send
@@ -100,17 +118,52 @@ function Button() {
100
118
}
101
119
102
120
function App ( ) {
121
+ const [ destination , setDestination ] = useState < PublicKey > ( ) ;
122
+ const [ amount , setAmount ] = useState < number > ( ) ;
123
+
124
+ const handleSetDestination = ( event : any ) => {
125
+ try {
126
+ setDestination ( new PublicKey ( event . target . value ) ) ;
127
+ } catch ( e ) {
128
+ setDestination ( undefined ) ;
129
+ }
130
+ } ;
131
+ const handleSetAmount = ( event : any ) => {
132
+ try {
133
+ setAmount ( parseInt ( event . target . value ) ) ;
134
+ } catch ( e ) {
135
+ setAmount ( undefined ) ;
136
+ }
137
+ } ;
138
+
103
139
return (
104
- < ConnectionProvider endpoint = { "https://api.devnet.solana.com" } >
140
+ < ConnectionProvider endpoint = { DEVNET_RPC_URL } >
105
141
< WalletProvider wallets = { [ ] } autoConnect >
106
142
< WalletModalProvider >
107
143
< div className = "App" >
108
144
< header className = "App-header" >
109
145
< img src = { logo } className = "App-logo" alt = "logo" />
110
146
< WalletMultiButton />
111
147
< WalletDisconnectButton />
112
- < p > Click to send a 1 usd to the hard-coded account</ p >
113
- < Button />
148
+ < p > Click to send the amount of USD in SOL</ p >
149
+ < p style = { { fontSize : "16px" } } >
150
+ Destination (paste a Solana public key)
151
+ </ p >
152
+ < input
153
+ type = "text"
154
+ value = { destination ? destination . toString ( ) : "" }
155
+ onChange = { handleSetDestination }
156
+ style = { { width : "100%" , height : "40px" , fontSize : "16px" } }
157
+ />
158
+ < p style = { { fontSize : "16px" } } > Amount (USD)</ p >
159
+ < input
160
+ type = "text"
161
+ value = { amount ? amount . toString ( ) : "" }
162
+ onChange = { handleSetAmount }
163
+ style = { { width : "100%" , height : "40px" , fontSize : "16px" } }
164
+ />
165
+
166
+ < Button destination = { destination } amount = { amount } />
114
167
</ header >
115
168
</ div >
116
169
</ WalletModalProvider >
0 commit comments