Maker App 2.0 Upgrade Guide
Update and Add New Dependencies
"@helium/address": "^4.8.1",
"@helium/currency-utils": "^0.0.26",
"@helium/react-native-sdk": "2.0.0",
"@helium/wallet-link": "^4.8.3",
"@metaplex-foundation/mpl-bubblegum": "^0.6.2",
"@pythnetwork/client": "^2.11.0",
"@solana/web3.js": "^1.73.0",
"axios-retry": "^3.3.1",
"cipher-base": "^1.0.4",
"stream": "^0.0.2"
Update App Providers
Apps must now be wrapped in a <SolanaProvider>
and the baseUrl
for <OnboardingProvider>
has
changed
A Solana Provider must be set with a Solana RPC. Because Helium makes use of Compressed NFTs, there are currently 3 RPC providers with support:
You can visit their websites and get set up with an RPC url.
// src/App.tsx
const { walletLinkToken } = useSelector((state: RootState) => state.app)
const [heliumWallet, setHeliumWallet] = useState<string>()
useEffect(() => {
if (!walletLinkToken) {
if (heliumWallet) {
setHeliumWallet('')
}
return
}
getAddress().then(setHeliumWallet)
}, [heliumWallet, walletLinkToken])
////////////////////////////////////////////////////
//👇👇👇 new provider 👇👇👇 /////////////////////////
<SolanaProvider
heliumWallet={heliumWallet}
cluster="mainnet-beta"
rpcEndpoint="https://your-solana-rpc.com"
>
{/* //////////////////////////////////////////////////////////////
Remove the /v2 from your onboarding url 👉👉👉👉👉👉👉👉👇
///////////////////////////////////////////////////////////👇 */}
<OnboardingProvider baseUrl="https://onboarding.dewi.org/api">
<HotspotBleProvider>
{/* The Rest of your app... */}
Testing Solana Pre-Migration
Before the migration to Solana has completed the v2 onboarding server will be used and transactions will still be submitted to the Helium blockchain. To test Solana before transition use these variables.
IT IS CRITICALLY IMPORTANT THAT YOU ONLY USE THESE FOR TESTING.
// src/App.tsx
<SolanaProvider
heliumWallet={heliumWallet}
rpcEndpoint="https://your-devnet-solana-rpc.com"
cluster="devnet"
solanaStatusOverride="complete"
>
<OnboardingProvider baseUrl="https://onboarding.web.test-helium.com/api">
For testing against devnet, you can use our testing maker:
ONBOARDING_MAKER_ADDRESS="14neTgRNZui1hSiHgE3LXjSfwkPU8BEB192MLXXDFnSY2xKjH51"
ONBOARDING_AUTH_TOKEN="pk_TgclExRP7rEXAEQlSgrrDwaZUHJAPcw/nNfkEpWOPCk=:sk_E1xc9OVq1/5oKLGD4RzxST7bl+LMnJhalkQ3vZp/QbOjNltvAmHyPolzA0Pb2HyTD68mZp4lETuC19Y+vI72nA==pk_TgclExRP7rEXAEQlSgrrDwaZUHJAPcw/nNfkEpWOPCk=:sk_E1xc9OVq1/5oKLGD4RzxST7bl+LMnJhalkQ3vZp/QbOjNltvAmHyPolzA0Pb2HyTD68mZp4lETuC19Y+vI72nA=="
ONBOARDING_MAKER_NAME="Test Maker"
Onboarding a Hotspot
When onboarding a Hotspot you must specify which hotspotTypes
it supports (eg iot
, mobile
)
You can optionally set elevation
, gain
, lat
, and lng
to avoid having to create a second
transaction.
Create Onboard Transactions
src/features/hotspots/setup/HotspotSetupConfirmLocationScreen.tsx
const { getOnboardingRecord, getOnboardTransactions } = useOnboarding()
let hotspotTypes = [] as HotspotType[]
const onboardingRecord = await getOnboardingRecord(params.hotspotAddress)
/*
TODO: Determine which network types this Hotspot supports
Could possibly use your maker address
*/
if (Config.MAKER_ADDRESS_5G === onboardingRecord?.maker.address) {
hotspotTypes = ['iot', 'mobile']
} else {
hotspotTypes = ['iot']
}
const onboardData = await getOnboardTransactions({
txn: params.addGatewayTxn,
hotspotAddress: params.hotspotAddress,
hotspotTypes,
elevation,
decimalGain: gain,
lat,
lng,
})
// pre-solana this txn will exist
setAddGatewayTxn(onboardData.addGatewayTxn)
// post-solana these txn(s) will exist
setSolanaTransactions(onboardData.solanaTransactions)
Updating a Hotspot
When updating a Hotspot you must specify which hotspotTypes
it supports (eg iot
, mobile
)
Create transactions
// src/features/hotspots/setup/HotspotSetupConfirmLocationScreen.tsx
const { getAssertData, getOnboardingRecord } = useOnboarding()
const data = await getAssertData({
decimalGain: gain,
elevation,
gateway: params.hotspotAddress,
lat,
lng,
owner: userAddress,
onboardingRecord,
hotspotTypes,
})
setAssertData(data)
setAssertLocationTxn(data.assertLocationTxn)
setSolanaTransactions(data.solanaTransactions)
Transferring a Hotspot
// src/features/transferHotspot/TransferHotspot.tsx
const { createTransferTransaction } = useOnboarding()
const { solanaTransactions, transferHotspotTxn } = await createTransferTransaction({
hotspotAddress,
userAddress,
newOwnerAddress,
})
Linking to Helium Wallet App for Signing
You must add solanaTransactions
to the signature request
src/features/hotspots/setup/HotspotTxnsProgressScreen.tsx
const updateParams = {
token,
platform: Platform.OS,
addGatewayTxn,
assertLocationTxn,
transferHotspotTxn,
solanaTransactions, // <---- !important!
} as SignHotspotRequest
const url = createUpdateHotspotUrl(updateParams)
Linking.openURL(url)
Submit Signed Transaction(s)
// src/features/hotspots/setup/HotspotTxnsSubmitScreen.tsx
const { submitTransactions } = useOnboarding()
const { pendingAssertTxn, pendingGatewayTxn, pendingTransferTxn, solanaTxnIds } =
await submitTransactions({
addGatewayTxn: params.gatewayTxn,
assertLocationTxn: params.assertTxn,
hotspotAddress: params.gatewayAddress,
solanaTransactions,
transferHotspotTxn: params.transferTxn,
})
Fetching Hotspots
const { getHotspots, getHotspotDetails } = useOnboarding()
useEffect(() => {
getHotspots({
heliumAddress,
// makerName: Config.MAKER_NAME,
})
}, [])
useEffect(() => {
getHotspotDetails({
address: hotspot.address,
type: hotspotTypes[0], // The types you support ('IOT', 'MOBILE')
})
}, [])
Update Wallet Link
The Helium Hotspot App is deprecated, Maker Apps should link to the Helium Wallet App. Add the hook
useCheckWalletLink()
to src/App.tsx
It will check to see if the user is linked to the Hotspot
app and prompt them to update their link
// src/App.tsx
import useCheckWalletLink from './utils/useCheckWalletLink'
const App = () => {
useCheckWalletLink()
}
Remove the ability for a new user to link to the Hotspot app. On the Welcome Screen you can now just link directly to the black Helium Wallet app.
// src/features/onboarding/welcome/WelcomeScreen.tsx
const { walletApp } = useDelegateApps()
const importAccount = useCallback(() => {
try {
const url = createWalletLinkUrl({
universalLink: walletApp?.universalLink,
requestAppId: getBundleId(),
callbackUrl: 'makerappscheme://',
appName: 'Maker App',
})
Linking.openURL(url)
} catch (error) {
// eslint-disable-next-line no-console
console.error(error)
}
}, [walletApp?.universalLink])
New Android 13 Permissions
Bluetooth scanning requires two new permissions on Android
AndroidManifest.xml
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
You must request these 3 permissions before scanning for bluetooth
const permissions = [
PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
]
The Maker Starter is now using react-native-permissions
to request/check permissions. If you'd
like to use the library, the setup guide can be found here
https://github.com/zoontek/react-native-permissions
Data Credits and Sol for Onboarding