diff --git a/Cargo.lock b/Cargo.lock index 39d330d..638ba20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -337,15 +337,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "libc" -version = "0.2.133" +version = "0.2.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" +checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" [[package]] name = "libm" @@ -454,9 +454,9 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "prettyplease" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a49e86d2c26a24059894a3afa13fd17d063419b05dfb83f06d9c3566060c3f5a" +checksum = "83fead41e178796ef8274dc612a7d8ce4c7e10ca35cd2c5b5ad24cac63aeb6c0" dependencies = [ "proc-macro2", "syn", @@ -464,9 +464,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.43" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" dependencies = [ "unicode-ident", ] @@ -574,18 +574,18 @@ checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "serde" -version = "1.0.144" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" +checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.144" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" +checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" dependencies = [ "proc-macro2", "quote", @@ -629,9 +629,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.3" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deb766570a2825fa972bceff0d195727876a9cdf2460ab2e52d455dc2de47fd9" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" [[package]] name = "sized-chunks" @@ -645,8 +645,8 @@ dependencies = [ [[package]] name = "soroban-auth" -version = "0.0.4" -source = "git+https://github.com/stellar/rs-soroban-sdk?rev=864a309b#864a309bca7ad91d6c7189fe87e018f64ad6ba06" +version = "0.1.0" +source = "git+https://github.com/stellar/rs-soroban-sdk?rev=3992556b#3992556b840ab1659599ba7c4671ad9231129bcc" dependencies = [ "ed25519-dalek", "rand 0.7.3", @@ -661,24 +661,24 @@ dependencies = [ "soroban-auth", "soroban-crowdfund-contract", "soroban-sdk", - "stellar-xdr 0.0.1", + "stellar-xdr", ] [[package]] name = "soroban-env-common" -version = "0.0.5" -source = "git+https://github.com/stellar/rs-soroban-env?rev=fb8a384e#fb8a384eb73b1d157c13b073efa9c82ff490119f" +version = "0.0.6" +source = "git+https://github.com/stellar/rs-soroban-env?rev=91cf595#91cf595508d475877f855619ad5baeb5f45a3885" dependencies = [ "soroban-env-macros", "soroban-wasmi", "static_assertions", - "stellar-xdr 0.0.2", + "stellar-xdr", ] [[package]] name = "soroban-env-guest" -version = "0.0.5" -source = "git+https://github.com/stellar/rs-soroban-env?rev=fb8a384e#fb8a384eb73b1d157c13b073efa9c82ff490119f" +version = "0.0.6" +source = "git+https://github.com/stellar/rs-soroban-env?rev=91cf595#91cf595508d475877f855619ad5baeb5f45a3885" dependencies = [ "soroban-env-common", "static_assertions", @@ -686,8 +686,8 @@ dependencies = [ [[package]] name = "soroban-env-host" -version = "0.0.5" -source = "git+https://github.com/stellar/rs-soroban-env?rev=fb8a384e#fb8a384eb73b1d157c13b073efa9c82ff490119f" +version = "0.0.6" +source = "git+https://github.com/stellar/rs-soroban-env?rev=91cf595#91cf595508d475877f855619ad5baeb5f45a3885" dependencies = [ "backtrace", "dyn-fmt", @@ -709,20 +709,20 @@ dependencies = [ [[package]] name = "soroban-env-macros" -version = "0.0.5" -source = "git+https://github.com/stellar/rs-soroban-env?rev=fb8a384e#fb8a384eb73b1d157c13b073efa9c82ff490119f" +version = "0.0.6" +source = "git+https://github.com/stellar/rs-soroban-env?rev=91cf595#91cf595508d475877f855619ad5baeb5f45a3885" dependencies = [ "itertools", "proc-macro2", "quote", - "stellar-xdr 0.0.2", + "stellar-xdr", "syn", ] [[package]] name = "soroban-native-sdk-macros" -version = "0.0.5" -source = "git+https://github.com/stellar/rs-soroban-env?rev=fb8a384e#fb8a384eb73b1d157c13b073efa9c82ff490119f" +version = "0.0.6" +source = "git+https://github.com/stellar/rs-soroban-env?rev=91cf595#91cf595508d475877f855619ad5baeb5f45a3885" dependencies = [ "itertools", "proc-macro2", @@ -732,8 +732,8 @@ dependencies = [ [[package]] name = "soroban-sdk" -version = "0.0.4" -source = "git+https://github.com/stellar/rs-soroban-sdk?rev=864a309b#864a309bca7ad91d6c7189fe87e018f64ad6ba06" +version = "0.1.0" +source = "git+https://github.com/stellar/rs-soroban-sdk?rev=3992556b#3992556b840ab1659599ba7c4671ad9231129bcc" dependencies = [ "bytes-lit", "ed25519-dalek", @@ -746,8 +746,8 @@ dependencies = [ [[package]] name = "soroban-sdk-macros" -version = "0.0.4" -source = "git+https://github.com/stellar/rs-soroban-sdk?rev=864a309b#864a309bca7ad91d6c7189fe87e018f64ad6ba06" +version = "0.1.0" +source = "git+https://github.com/stellar/rs-soroban-sdk?rev=3992556b#3992556b840ab1659599ba7c4671ad9231129bcc" dependencies = [ "darling", "itertools", @@ -756,14 +756,14 @@ dependencies = [ "sha2 0.10.6", "soroban-env-common", "soroban-spec", - "stellar-xdr 0.0.2", + "stellar-xdr", "syn", ] [[package]] name = "soroban-spec" -version = "0.0.4" -source = "git+https://github.com/stellar/rs-soroban-sdk?rev=864a309b#864a309bca7ad91d6c7189fe87e018f64ad6ba06" +version = "0.1.0" +source = "git+https://github.com/stellar/rs-soroban-sdk?rev=3992556b#3992556b840ab1659599ba7c4671ad9231129bcc" dependencies = [ "base64", "darling", @@ -776,7 +776,7 @@ dependencies = [ "serde_json", "sha2 0.10.6", "soroban-env-host", - "stellar-xdr 0.0.2", + "stellar-xdr", "syn", "thiserror", "wasmparser", @@ -784,8 +784,8 @@ dependencies = [ [[package]] name = "soroban-wasmi" -version = "0.16.0" -source = "git+https://github.com/stellar/wasmi?rev=a61b6df#a61b6dffa0a13aca70b046fc11e379a3fde31147" +version = "0.16.0-soroban1" +source = "git+https://github.com/stellar/wasmi?rev=d1ec0036#d1ec0036a002a14227b0b09117f0dc6182ae19e4" dependencies = [ "soroban-wasmi_core", "spin", @@ -794,8 +794,8 @@ dependencies = [ [[package]] name = "soroban-wasmi_core" -version = "0.2.0" -source = "git+https://github.com/stellar/wasmi?rev=a61b6df#a61b6dffa0a13aca70b046fc11e379a3fde31147" +version = "0.16.0-soroban1" +source = "git+https://github.com/stellar/wasmi?rev=d1ec0036#d1ec0036a002a14227b0b09117f0dc6182ae19e4" dependencies = [ "downcast-rs", "libm", @@ -827,14 +827,8 @@ dependencies = [ [[package]] name = "stellar-xdr" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "015594b09942b9f9cbe6972ba8c7de3a05a25c4994bbc7282f5f2fa6d28a81c4" - -[[package]] -name = "stellar-xdr" -version = "0.0.2" -source = "git+https://github.com/stellar/rs-stellar-xdr?rev=88ded341#88ded341ffbf54372ce851f766610ef978784d2a" +version = "0.0.6" +source = "git+https://github.com/stellar/rs-stellar-xdr?rev=5cca712b#5cca712b64a928574bc6f142a161bd8bdfe42b23" dependencies = [ "base64", "serde", @@ -854,9 +848,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.100" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e" +checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" dependencies = [ "proc-macro2", "quote", @@ -877,18 +871,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c53f98874615aea268107765aa1ed8f6116782501d18e53d08b471733bea6c85" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8b463991b4eab2d801e724172285ec4195c650e8ec79b149e6c2a8e6dd3f783" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ "proc-macro2", "quote", @@ -918,9 +912,9 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "unicode-ident" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-xid" diff --git a/Cargo.toml b/Cargo.toml index a9c7b3a..4b7e2f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,14 +16,14 @@ codegen-units = 1 lto = true [patch.crates-io] -soroban-sdk = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "864a309b" } -soroban-spec = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "864a309b" } -soroban-auth = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "864a309b" } -soroban-sdk-macros = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "864a309b" } -soroban-env-common = { git = "https://github.com/stellar/rs-soroban-env", rev = "fb8a384e" } -soroban-env-guest = { git = "https://github.com/stellar/rs-soroban-env", rev = "fb8a384e" } -soroban-env-host = { git = "https://github.com/stellar/rs-soroban-env", rev = "fb8a384e" } -soroban-env-macros = { git = "https://github.com/stellar/rs-soroban-env", rev = "fb8a384e" } -soroban-native-sdk-macros = { git = "https://github.com/stellar/rs-soroban-env", rev = "fb8a384e" } -stellar-xdr = { git = "https://github.com/stellar/rs-stellar-xdr", rev = "88ded341" } -wasmi = { package = "soroban-wasmi", git = "https://github.com/stellar/wasmi", rev = "a61b6df" } +soroban-sdk = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "3992556b" } +soroban-spec = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "3992556b" } +soroban-auth = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "3992556b" } +soroban-sdk-macros = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "3992556b" } +soroban-env-common = { git = "https://github.com/stellar/rs-soroban-env", rev = "91cf595" } +soroban-env-guest = { git = "https://github.com/stellar/rs-soroban-env", rev = "91cf595" } +soroban-env-host = { git = "https://github.com/stellar/rs-soroban-env", rev = "91cf595" } +soroban-env-macros = { git = "https://github.com/stellar/rs-soroban-env", rev = "91cf595" } +soroban-native-sdk-macros = { git = "https://github.com/stellar/rs-soroban-env", rev = "91cf595" } +stellar-xdr = { git = "https://github.com/stellar/rs-stellar-xdr", rev = "5cca712b" } +wasmi = { package = "soroban-wasmi", git = "https://github.com/stellar/wasmi", rev = "d1ec0036" } diff --git a/README.md b/README.md index d35716d..2ae9408 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,42 @@ backed by smart contracts on Stellar. ## Getting Started -### Backend +### Backend (Local Sandbox) 1. Install the soroban-cli from https://soroban.stellar.org/docs/getting-started/setup#install-the-soroban-cli -2. Run `./initialize.sh` to load the contracts and initialize it. +2. Run the backend with `soroban-cli serve` +3. Run `./initialize.sh sandbox` to load the contracts and initialize it. - Note: this will create a `.soroban` sub-directory, to contain the sandbox network data. -3. Run the backend with `soroban-cli serve` +4. Configure Freighter + a. Install the custom Freighter Soroban release from https://github.com/stellar/freighter/releases/tag/v2.6.0-beta.2 + b. Enable "Experimental Mode" in the settings (gear icon). + c. Add a custom network: + | Name | Sandbox | + | URL | http://localhost:8000/soroban/rpc | + | Passphrase | Local Sandbox Stellar Network ; September 2022 | + | Allow HTTP connection | Enabled | + | Switch to this network | Enabled | + +### Backend (Local Standalone Network) + +1. Install the soroban-cli from https://soroban.stellar.org/docs/getting-started/setup#install-the-soroban-cli +2. Run the backend docker container with `./quickstart.sh standalone`, and wait for it to start. +3. Run `./initialize.sh standalone` to load the contracts and initialize it. + - Note: this state will be lost if the quickstart docker container is removed. +4. Configure Freighter + a. Install the custom Freighter Soroban release from https://github.com/stellar/freighter/releases/tag/v2.6.0-beta.2 + b. Enable "Experimental Mode" in the settings (gear icon). + c. Add a custom network: + | Name | Standalone | + | URL | http://localhost:8000/soroban/rpc | + | Passphrase | Standalone Network ; February 2017 | + | Allow HTTP connection | Enabled | + | Switch to this network | Enabled | +5. Add some standalone network lumens to your Freighter wallet. + a. Copy the address for your freighter wallet. + b. Visit `http://localhost:8000/friendbot?addr=` + ### Frontend diff --git a/components/molecules/deposits/index.tsx b/components/molecules/deposits/index.tsx index 4032528..aeb752d 100644 --- a/components/molecules/deposits/index.tsx +++ b/components/molecules/deposits/index.tsx @@ -23,7 +23,7 @@ export interface IDepositsProps { export function Deposits(props: IDepositsProps) { const useLoadDeposits = (): ContractValue => { return useContractValue( - Constants.CrowndfundId, + Constants.CrowdfundId, 'balance', accountIdentifier( SorobanSdk.StrKey.decodeEd25519PublicKey(props.address) diff --git a/components/molecules/form-pledge/index.tsx b/components/molecules/form-pledge/index.tsx index 97150c0..b5ecb4d 100644 --- a/components/molecules/form-pledge/index.tsx +++ b/components/molecules/form-pledge/index.tsx @@ -22,8 +22,6 @@ export interface IFormPledgeProps { crowdfundId: string decimals: number networkPassphrase: string - source: Account - address: string symbol?: string } @@ -73,8 +71,10 @@ const FormPledge: FunctionComponent = props => { const handleSubmit = async (): Promise => { setSubmitting(true) - let { sequence } = await server.getAccount(props.address) - let source = new SorobanSdk.Account(props.address, sequence) + if (!server) throw new Error("Not connected to server") + + let { sequence } = await server.getAccount(props.account) + let source = new SorobanSdk.Account(props.account, sequence) let invoker = xdr.ScVal.scvObject( xdr.ScObject.scoVec([xdr.ScVal.scvSymbol('Invoker')]) ) @@ -237,6 +237,9 @@ const FormPledge: FunctionComponent = props => { title={`Mint ${amount.decimalPlaces(decimals).toString()} ${symbol}`} onClick={async () => { setSubmitting(true) + + if (!server) throw new Error("Not connected to server") + let { sequence } = await server.getAccount(Constants.TokenAdmin) let source = new SorobanSdk.Account(Constants.TokenAdmin, sequence) let invoker = xdr.ScVal.scvObject( @@ -259,7 +262,7 @@ const FormPledge: FunctionComponent = props => { recipient, amountScVal ) - let result = await sendTransaction(mint) + let result = await sendTransaction(mint, { secretKey: Constants.TokenAdminSecretKey }) // TODO: Show some user feedback while we are awaiting, and then based on the result console.debug(result) setSubmitting(false) diff --git a/components/organisms/pledge/index.tsx b/components/organisms/pledge/index.tsx index 0c8b089..c6c9129 100644 --- a/components/organisms/pledge/index.tsx +++ b/components/organisms/pledge/index.tsx @@ -25,9 +25,6 @@ const Pledge: FunctionComponent = () => { const networkPassphrase = activeChain?.networkPassphrase ?? '' - // TODO: Stub dummy data for now. replace with freighter wallet account - const source = new SorobanSdk.Account(Constants.Account, '0') - // Call the contract rpcs to fetch values const useLoadToken = (): any => { return { @@ -115,13 +112,11 @@ const Pledge: FunctionComponent = () => { {!Utils.isExpired(deadlineDate) && (account ? ( ) : ( diff --git a/contracts/crowdfund/Cargo.toml b/contracts/crowdfund/Cargo.toml index 95f8613..06fea33 100644 --- a/contracts/crowdfund/Cargo.toml +++ b/contracts/crowdfund/Cargo.toml @@ -13,12 +13,12 @@ export = [] testutils = ["soroban-sdk/testutils", "soroban-auth/testutils", "dep:stellar-xdr"] [dependencies] -soroban-sdk = { version = "0.0.4" } -soroban-auth = { version = "0.0.4" } -stellar-xdr = { version = "0.0.1", features = ["next", "std"], optional = true } +soroban-sdk = { version = "0.1.0" } +soroban-auth = { version = "0.1.0" } +stellar-xdr = { version = "0.0.6", features = ["next", "std"], optional = true } [dev_dependencies] -soroban-sdk = { version = "0.0.4", features = ["testutils"] } -soroban-auth = { version = "0.0.4", features = ["testutils"] } +soroban-sdk = { version = "0.1.0", features = ["testutils"] } +soroban-auth = { version = "0.1.0", features = ["testutils"] } soroban-crowdfund-contract = { path = ".", default-features = false, features = ["testutils"] } rand = { version = "0.7.3" } diff --git a/contracts/token/soroban_token_spec.wasm b/contracts/token/soroban_token_spec.wasm index ed5e094..831e24d 100755 Binary files a/contracts/token/soroban_token_spec.wasm and b/contracts/token/soroban_token_spec.wasm differ diff --git a/initialize.sh b/initialize.sh index 0b5fee4..a1332d5 100755 --- a/initialize.sh +++ b/initialize.sh @@ -4,13 +4,42 @@ set -e # TODO: Set the recipient to something reasonable here. Probably whatever account # soroban is running stuff as? -# This is an Identifier for Account GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF # TODO: Have a nicer way to build Identifiers on the CLI -admin="AAAABAAAAAEAAAAAAAAAAgAAAAUAAAAHQWNjb3VudAAAAAAEAAAAAQAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +TOKEN_ADMIN=GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI +TOKEN_ADMIN_IDENTIFIER="AAAABAAAAAEAAAAAAAAAAgAAAAUAAAAHQWNjb3VudAAAAAAEAAAAAQAAAAcAAAAAc3b96I5M1hzA+ylKF4az8dBh9fLxyldGX6qTIhG5RtY=" + +case "$1" in +standalone) + echo "Using standalone network" + export SOROBAN_RPC_URL=http://localhost:8000/soroban/rpc + export SOROBAN_NETWORK_PASSPHRASE="Standalone Network ; February 2017" + export SOROBAN_SECRET_KEY="SC5O7VZUXDJ6JBDSZ74DSERXL7W3Y5LTOAMRF7RQRL3TAGAPS7LUVG3L" + + echo Fund token admin account from friendbot + curl "$SOROBAN_RPC_URL/friendbot?addr=$TOKEN_ADMIN" + ;; +futurenet) + echo "Using Futurenet network" + export SOROBAN_RPC_URL=http://localhost:8000/soroban/rpc + export SOROBAN_NETWORK_PASSPHRASE="Test SDF Future Network ; October 2022" + export SOROBAN_SECRET_KEY="SC5O7VZUXDJ6JBDSZ74DSERXL7W3Y5LTOAMRF7RQRL3TAGAPS7LUVG3L" + # TODO: Use friendbot to fund the token admin, or figure our token admin here... + # curl "$SOROBAN_RPC_URL/friendbot?addr=$TOKEN_ADMIN" + ;; +""|sandbox) + # no-op + ;; +*) + echo "Usage: $0 sandbox|standalone|futurenet" + exit 1 + ;; +esac + echo Deploy the token contract TOKEN_ID="$( soroban token create \ + --admin "$TOKEN_ADMIN" \ --name "Example Token" \ --symbol "EXT" \ --decimal 2 @@ -33,7 +62,8 @@ deadline="$(($(date +"%s") + 86400))" soroban invoke \ --id "$CROWDFUND_ID" \ --fn initialize \ - --arg-xdr "$admin" \ + --arg-xdr "$TOKEN_ADMIN_IDENTIFIER" \ --arg "$deadline" \ --arg "1000000000" \ - --arg "$TOKEN_ID" + --arg "$TOKEN_ID" \ + --wasm target/wasm32-unknown-unknown/release/soroban_crowdfund_contract.wasm diff --git a/pages/_app.tsx b/pages/_app.tsx index 4b7e296..7ba2640 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -7,8 +7,7 @@ import { getDefaultWallets, } from "../wallet"; -const chains: ChainMetadata[] = [chain.sandbox]; -const serverUrl = 'http://localhost:8080/api/v1/jsonrpc'; +const chains: ChainMetadata[] = [chain.sandbox, chain.standalone]; const { wallets } = getDefaultWallets({ appName: "Example Stellar App", @@ -21,8 +20,6 @@ function MyApp({ Component, pageProps }: AppProps) { chains={chains} appName={"Example Stellar App"} wallets={wallets} - serverUrl={serverUrl} - allowHttp > diff --git a/quickstart.sh b/quickstart.sh index 1148528..fa44bf2 100755 --- a/quickstart.sh +++ b/quickstart.sh @@ -2,7 +2,7 @@ set -e -REVISION=574897620355e2f7486a8cc5586597babd95c85cfa6f148a06470dc80012c2e2 +REVISION=42641a3dbc46565584e424697f042aec7d5063681cc22a0f490f78fa1f1e1de0 case "$1" in standalone) diff --git a/shared/constants.tsx b/shared/constants.tsx index 8f64ff2..7128e36 100644 --- a/shared/constants.tsx +++ b/shared/constants.tsx @@ -1,14 +1,12 @@ -const Account = 'GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ' const CrowdfundId = process.env.CROWDFUND_ID ?? '' -const Address = 'GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI' -const TokenAdmin = 'GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF' +const TokenAdmin = 'GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI' +const TokenAdminSecretKey = 'SC5O7VZUXDJ6JBDSZ74DSERXL7W3Y5LTOAMRF7RQRL3TAGAPS7LUVG3L' const TokenId = process.env.TOKEN_ID ?? '' const Constants = { - Account, CrowdfundId, - Address, TokenAdmin, + TokenAdminSecretKey, TokenId, } diff --git a/wallet/AppContext.tsx b/wallet/AppContext.tsx index 1edfd63..aa89b7a 100644 --- a/wallet/AppContext.tsx +++ b/wallet/AppContext.tsx @@ -19,7 +19,7 @@ export interface AppContextType { activeChain?: ChainMetadata; address?: string; activeWallet?: Wallet; - server: SorobanSdk.Server; + server?: SorobanSdk.Server; connect: () => Promise; } diff --git a/wallet/Wallet.tsx b/wallet/Wallet.tsx index 2e8feaa..a61ffb3 100644 --- a/wallet/Wallet.tsx +++ b/wallet/Wallet.tsx @@ -1,28 +1,10 @@ export type InstructionStepName = 'install' | 'create' | 'scan'; -export type ConnectorArgs = { - chainId?: number; -}; - -type WalletConnector = { - mobile?: { - getUri?: () => Promise; - }; - desktop?: { - getUri?: () => Promise; - }; - qrCode?: { - getUri: () => Promise; - instructions?: { - learnMoreUrl: string; - steps: { - step: InstructionStepName; - title: string; - description: string; - }[]; - }; - }; -}; +export interface NetworkDetails { + network: string; + networkUrl: string; + networkPassphrase: string; +} export type Wallet = { id: string; @@ -38,11 +20,9 @@ export type Wallet = { qrCode?: string; }; isConnected: () => boolean; + getNetworkDetails: () => Promise; getPublicKey: () => Promise; signTransaction: (xdr: string, opts?: { network?: string; networkPassphrase?: string; accountToSign?: string }) => Promise; - createConnector: (connectorArgs: { - chainId?: number; - }) => WalletConnector; }; export type WalletList = { diff --git a/wallet/components/WalletProvider.tsx b/wallet/components/WalletProvider.tsx index d722bf7..476805b 100644 --- a/wallet/components/WalletProvider.tsx +++ b/wallet/components/WalletProvider.tsx @@ -9,8 +9,6 @@ export interface WalletProviderProps { autoconnect?: boolean; chains: WalletChain[]; children: React.ReactNode; - serverUrl?: string; - allowHttp?: boolean; wallets: WalletList; } @@ -19,8 +17,6 @@ export function WalletProvider({ autoconnect = false, chains, children, - serverUrl, - allowHttp = false, wallets, }: WalletProviderProps) { @@ -34,10 +30,28 @@ export function WalletProvider({ wallets, activeWallet, activeChain: chains.length == 1 ? chains[0] : undefined, - server: new SorobanSdk.Server(serverUrl || "", {allowHttp}), connect: async () => { - let address = await appContext.activeWallet?.getPublicKey(); - setAppContext(c => ({ ...c, address })); + let networkDetails = await appContext.activeWallet?.getNetworkDetails() + const supported = networkDetails && chains.find(c => c.networkPassphrase === networkDetails?.networkPassphrase) + const activeChain = networkDetails && { + id: supported?.id ?? networkDetails.networkPassphrase, + name: supported?.name ?? networkDetails.network, + networkPassphrase: networkDetails.networkPassphrase, + iconBackground: supported?.iconBackground, + iconUrl: supported?.iconUrl, + unsupported: !supported, + } + let address = await appContext.activeWallet?.getPublicKey() + let server = networkDetails && new SorobanSdk.Server( + networkDetails.networkUrl, + { allowHttp: networkDetails.networkUrl.startsWith("http://") } + ) + setAppContext(c => ({ + ...c, + activeChain, + address, + server, + })); }, }); diff --git a/wallet/connectors/freighter/index.tsx b/wallet/connectors/freighter/index.tsx index c73771c..ec5d7e9 100644 --- a/wallet/connectors/freighter/index.tsx +++ b/wallet/connectors/freighter/index.tsx @@ -1,7 +1,7 @@ /* eslint-disable sort-keys-fix/sort-keys-fix */ import freighterApi from "@stellar/freighter-api"; import { WalletChain } from '../../WalletChainContext'; -import { Wallet } from '../../Wallet'; +import { NetworkDetails, Wallet } from '../../Wallet'; export interface FreighterOptions { appName?: string; @@ -24,15 +24,14 @@ export function freighter(_: FreighterOptions): Wallet { isConnected(): boolean { return !!freighterApi?.isConnected() }, + getNetworkDetails(): Promise { + return freighterApi.getNetworkDetails() + }, getPublicKey(): Promise { return freighterApi.getPublicKey() }, signTransaction(xdr: string, opts?: { network?: string; networkPassphrase?: string; accountToSign?: string }): Promise { return freighterApi.signTransaction(xdr, opts) }, - createConnector: _args => { - // TODO: Implement this - return {} - }, } }; diff --git a/wallet/hooks/useContractValue.tsx b/wallet/hooks/useContractValue.tsx index 7da245a..94e0b8d 100644 --- a/wallet/hooks/useContractValue.tsx +++ b/wallet/hooks/useContractValue.tsx @@ -19,8 +19,12 @@ export function useContractValue(contractId: string, method: string, ...params: React.useEffect(() => { if (!activeChain) { - setValue({ error: "No active chain" }); - return; + setValue({ error: "No active chain" }) + return + } + if (!server) { + setValue({ error: "Not connected to server" }) + return } (async () => { diff --git a/wallet/hooks/useSendTransaction.tsx b/wallet/hooks/useSendTransaction.tsx index 4ca1014..ddb89a7 100644 --- a/wallet/hooks/useSendTransaction.tsx +++ b/wallet/hooks/useSendTransaction.tsx @@ -21,6 +21,7 @@ type Transaction = SorobanSdk.Transaction | SorobanSdk.FeeBumpTransaction; export interface SendTransactionOptions { timeout?: number; skipAddingFootprint?: boolean + secretKey?: string; } // useSendTransaction is a hook that returns a function that can be used to @@ -35,6 +36,9 @@ export function useSendTransaction(defaultTxn?: Transaction, defaultO if (!txn || !activeWallet || !activeChain) { throw new Error("No transaction or wallet or chain"); } + + if (!server) throw new Error("Not connected to server") + const { timeout, skipAddingFootprint, @@ -53,7 +57,14 @@ export function useSendTransaction(defaultTxn?: Transaction, defaultO txn = addFootprint(txn, networkPassphrase, footprint); } - const signed = await activeWallet.signTransaction(txn.toXDR(), { networkPassphrase }); + let signed = ""; + if (passedOptions?.secretKey) { + const keypair = SorobanSdk.Keypair.fromSecret(passedOptions.secretKey); + txn.sign(keypair); + signed = txn.toXDR(); + } else { + signed = await activeWallet.signTransaction(txn.toXDR(), { networkPassphrase }); + } const transactionToSubmit = SorobanSdk.TransactionBuilder.fromXDR(signed, networkPassphrase); const { id } = await server.sendTransaction(transactionToSubmit); @@ -111,7 +122,7 @@ function addFootprint(raw: Transaction, networkPassphrase: string, footprint: So return addFootprint(raw.innerTransaction, networkPassphrase, footprint); } // TODO: Figure out a cleaner way to clone this transaction. - const source = new SorobanSdk.Account(raw.source, raw.sequence); + const source = new SorobanSdk.Account(raw.source, `${parseInt(raw.sequence)-1}`); const txn = new SorobanSdk.TransactionBuilder(source, { fee: raw.fee, memo: raw.memo, diff --git a/wallet/provideWalletChains.tsx b/wallet/provideWalletChains.tsx index 6c549ec..99c6557 100644 --- a/wallet/provideWalletChains.tsx +++ b/wallet/provideWalletChains.tsx @@ -8,39 +8,47 @@ export type ChainName = | 'futurenet' | 'public' | 'testnet' - | 'sandbox'; + | 'sandbox' + | 'standalone'; export type ChainMetadata = WalletChain; const chainMetadataByName: Record = { public: { - id: "0", + id: "public", name: "Public", networkPassphrase: SorobanSdk.Networks.PUBLIC, iconBackground: '#e84141', // iconUrl: async () => (await import('./chainIcons/public.svg')).default, }, testnet: { - id: "1", + id: "testnet", name: "Testnet", networkPassphrase: SorobanSdk.Networks.TESTNET, iconBackground: '#484c50', // iconUrl: async () => (await import('./chainIcons/testnet.svg')).default, }, futurenet: { - id: "2", + id: "futurenet", name: "Futurenet", networkPassphrase: SorobanSdk.Networks.FUTURENET, iconBackground: '#96bedc', // iconUrl: async () => (await import('./chainIcons/futurenet.svg')).default, }, sandbox: { - id: "3", + id: "sandbox", name: "Sandbox", networkPassphrase: SorobanSdk.Networks.SANDBOX, iconBackground: '#dac695', // iconUrl: async () => (await import('./chainIcons/futurenet.svg')).default, }, + standalone: { + id: "standalone", + name: "Standalone", + networkPassphrase: "Standalone Network ; February 2017", + iconBackground: '#dac695', + // iconUrl: async () => (await import('./chainIcons/futurenet.svg')).default, + }, }; const chainMetadataById = Object.fromEntries(