diff --git a/src/pages/build-apps/guides/authentication.md b/src/pages/build-apps/guides/authentication.md index 93b40578..81d13110 100644 --- a/src/pages/build-apps/guides/authentication.md +++ b/src/pages/build-apps/guides/authentication.md @@ -49,6 +49,14 @@ The first two of these functions are particularly relevant to [data storage with [Learn more about keypairs](#key-pairs) used by authentication. +## Install dependency + +The following dependency must be installed: + +``` +npm install @stacks/connect +``` + ## Initiate userSession object Apps keep track of user authentication state with the `userSession` object, initiated with the `UserSession` and `AppConfig` classes: @@ -144,6 +152,12 @@ If the user has indeed confirmed authentication in the context of a popup window It will then trigger the `finished` function provided above, which can be used similarly to save the user's information into their session as retrieved with `userSession.loadUserData()`. +## Usage in React Apps + +Import the `useConnect` from the `connect` package to integrate transaction signing more seamlessly into React apps. + +TODO: Add guidance for authentication with React + ## Key pairs Authentication with Stacks makes extensive use of public key cryptography generally and ECDSA with the `secp256k1` curve in particular. diff --git a/src/pages/build-apps/guides/data-storage.md b/src/pages/build-apps/guides/data-storage.md index 4a928ef4..e54d7269 100644 --- a/src/pages/build-apps/guides/data-storage.md +++ b/src/pages/build-apps/guides/data-storage.md @@ -19,6 +19,15 @@ Storing data off the Stacks blockchain ensures that apps can provide users with [See the Todos app tutorial](/build-apps/tutorials/todos) for a concrete example of this functionality in practice. +## Install dependencies + +The following dependencies must be installed: + +``` +npm install @stacks/connect +npm install @stacks/storage +``` + ## Initiate session Users must authenticate to an app before the `storage` package will work to save or retrieve data on their behalf. diff --git a/src/pages/build-apps/guides/transaction-signing.md b/src/pages/build-apps/guides/transaction-signing.md index 36557acc..dcd81d92 100644 --- a/src/pages/build-apps/guides/transaction-signing.md +++ b/src/pages/build-apps/guides/transaction-signing.md @@ -15,64 +15,60 @@ This guide explains how to prompt users to sign transactions and broadcast them Transaction signing provides a way for users execute [Clarity smart contracts](/write-smart-contracts/overview) that are relevant to your app then handle the result immediately. -Users can sign transactions that exchange fungible or non-fungible tokens with upfront guarantees while retaining complete control over their digital assets. +Users can sign transactions that exchange fungible or non-fungible tokens with upfront guarantees that help them retain control over their digital assets. + +There are three types of transactions: + +1. STX transfer +2. Contract deployment +3. Contract execution [See the public registry tutorial](/build-apps/tutorials/public-registry) for a concrete example of this functionality in practice. -## How it works +## Install dependency -For your app's users to be able to execute a smart contract function, they need to sign and broadcast a transaction. +The following dependency must be installed: + +``` +npm install @stacks/connect +``` -It's important that users remain in control of the private keys that sign these transactions. Connect provides an easy-to-use workflow that allows your users to securely sign transactions. +## Initiate session -Connect allows you to open the authenticator with parameters indicating the details of the transaction - like the smart -contract address, function name, and specific arguments. Your users get the chance to see these details, and then sign -and broadcast the transaction in a single click. Their transaction will be securely signed and broadcasted onto the -Stacks blockchain. After this is done, a callback is fired to allow you to update your app. +Users must authenticate to an app before the `connect` package will work to prompt them for signing and broadcasting transactions to the Stacks blockchain with an authenticator such as [the Stacks Wallet](https://blockstack.org/wallet). -## Calling Clarity Contract Functions +[See the authentication guide](/build-apps/guides/authentication) before proceeding to integrate the following transaction signing capabilities in cases where `userSession.isUserSignedIn()` returns `true`. -Once you have a Clarity smart contract built and deployed, you'll naturally want to allow your app's users to interact -with it. +## Prompt to transfer STX -To initiate a contract call transaction, use the `openContractCall` function. +Call the `openSTXTransfer` function provided by the `connect` package to trigger the display of a transaction signing prompt for transferring STX: ```tsx -import { openContractCall } from '@stacks/connect'; +import { openSTXTransfer } from '@stacks/connect'; -const myStatus = 'hey there'; -const options = { - contractAddress: 'ST22T6ZS7HVWEMZHHFK77H4GTNDTWNPQAX8WZAKHJ', - contractName: 'status', - functionName: 'write-status!', - functionArgs: [ - { - type: 'buff', - value: myStatus, - }, - ], +openSTXTransfer({ + recipient: 'ST2EB9WEQNR9P0K28D2DC352TM75YG3K0GT7V13CV', + amount: '100', + memo: 'Reimbursement', authOrigin, appDetails: { - name: 'SuperApp', - icon: 'https://example.com/icon.png', + name: 'My App', + icon: window.location.origin + '/my-app-logo.svg', }, finished: data => { - console.log('TX ID:', data.txId); - console.log('Raw TX:', data.txRaw); + console.log('Transaction ID:', data.txId); + console.log('Raw transaction:', data.txRaw); }, -}; - -await openContractCall(options); +}); ``` -There are some required parameters needed when calling `openContractCall`. Here is the exact interface which describes what options you have: +Several parameters are available for calling `openSTXTransfer`. Here's the exact interface for them: ```tsx -interface ContractCallOptions { - contractAddress: string; - functionName: string; - contractName: string; - functionArgs?: any[]; +interface STXTransferOptions { + recipient: string; + amount: string; + memo?: string; authOrigin?: string; appDetails: { name: string; @@ -82,75 +78,44 @@ interface ContractCallOptions { } ``` -| parameter | type | optional | description | -| --------------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| contractAddress | string | false | The Stacks address that published this contract | -| contractName | string | false | The name that was used when publishing this contract | -| functionName | string | false | The name of the function you're calling. This needs to be a [public function](/references/language-functions#define-public). | -| functionArgs | array | false | The arguments you're calling the function with. You'll need to provide the Clarity type with each argument. See the below section for details. Defaults to `[]`. | -| appDetails | object | false | A dictionary that includes `name` and `icon` | -| finished | function | false | A callback that is fired when the transaction is signed and broadcasted. Your callback will receive an object back with a `txId` and a `txRaw`, both of which are strings. | -| authOrigin | string | true | The location of the authenticator. This is only necessary when developing the authenticator locally, or when using beta features. Defaults to `"https://app.blockstack.org"`. | - -### Passing Clarity types with function arguments - -To be able to serialize your transaction properly, you need to provide the appropriate Clarity type with each argument. -These types are named the same as they are in Clarity. The `value` that you pass must be a string. The types you can pass are: +| parameter | type | required | description | +| ---------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| recipient | string | true | STX address for recipient of transfer | +| amount | string | true | Amount of microstacks (µSTX, with 1,000,000 µSTX per 1 STX) to be transferred provided as string to prevent floating point errors. | +| appDetails | object | true | Dictionary that requires `name` and `icon` for app | +| finished | function | true | Callback executed by app when transaction has been signed and broadcasted. It received an object back with `txId` and `txRaw` properties, both of which are strings. | +| memo | string | false | Optional memo for inclusion with transaction | +| authOrigin | string | false | URL of authenticator to use for prompting signature and broadcast. Defaults to `https://wallet.hiro.so` for the Stacks Wallet, which is handled by the Stacks Wallet browser extension if installed. | -- `uint` - for example `"240"` -- `int` - for example `"12"` -- `bool` - can be `true`, `false`, `0` or `1` -- `buff` - for example `"asdf"` -- `principal` - This can be a contract principal, or a standard principal. - [Read more about principals](/write-smart-contracts/principals). Examples: `"ST22T6ZS7HVWEMZHHFK77H4GTNDTWNPQAX8WZAKHJ"` - or `"ST22T6ZS7HVWEMZHHFK77H4GTNDTWNPQAX8WZAKHJ.my-contract"`. +## Prompt to deploy smart contract -Using these types, each argument is an object with the keys `type` and `value`. For example: +Call the `openContractDeploy` function provided by the `connect` package to trigger the display of a transaction signing prompt for deploying a smart contract: ```tsx -const functionArguments = [ - { - type: 'buff', - value: 'hello, world', - }, - { - type: 'uint', - value: '1', - }, -]; -``` - -If you're using TypeScript, these Clarity types can be imported as `ContractCallArgumentType` from `@stacks/connect`. - -## Stacks (STX) Token Transfers - -STX token transfers can be initiated with the `openSTXTransfer` function. +import { openContractDeploy } from '@blockstack/connect'; -```tsx -import { openSTXTransfer } from '@stacks/connect'; +const codeBody = '(begin (print "hello, world"))'; -openSTXTransfer({ - recipient: 'ST2EB9WEQNR9P0K28D2DC352TM75YG3K0GT7V13CV', - amount: '100', - memo: 'Testing STX Transfers!', - authOrigin, +openContractDeploy({ + contractName: 'my-contract-name', + codeBody, appDetails: { - name: 'SuperApp', - icon: 'https://example.com/icon.png', + name: 'My App', + icon: window.location.origin + '/my-app-logo.svg', }, finished: data => { - console.log(data.txId); + console.log('Transaction ID:', data.txId); + console.log('Raw transaction:', data.txRaw); }, }); ``` -When calling `openSTXTransfer`, you need to specify a few details. Here are the options you have: +Several parameters are available for calling `openContractDeploy`. Here's the exact interface for them: ```tsx -interface STXTransferOptions { - recipient: string; - amount: string; - memo?: string; +interface ContractDeployOptions { + codeBody: string; + contractName: string; authOrigin?: string; appDetails: { name: string; @@ -160,43 +125,55 @@ interface STXTransferOptions { } ``` -| parameter | type | optional | description | -| ---------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| recipient | string | false | The STX Address for the recipient of this STX transfer | -| amount | string | false | The amount of microstacks (µSTX) to be transferred. This argument is a string to prevent floating point errors. There are 1,000,000 µSTX per STX. | -| memo | string | true | An optional memo to include in the transaction. | -| appDetails | object | false | A dictionary that includes `name` and `icon` | -| finished | function | false | A callback that is fired when the transaction is signed and broadcasted. Your callback will receive an object back with a `txId` and a `txRaw`, both of which are strings. | -| authOrigin | string | true | Location of the authenticator to use for signing. Defaults `"https://app.blockstack.org"`. | +| parameter | type | required | description | +| ------------ | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| codeBody | string | true | Clarity source code for contract | +| contractName | string | true | Name for contract | +| appDetails | object | true | Dictionary that requires `name` and `icon` for app | +| finished | function | true | Callback executed by app when transaction has been signed and broadcasted. It received an object back with `txId` and `txRaw` properties, both of which are strings. | +| authOrigin | string | false | URL of authenticator to use for prompting signature and broadcast. Defaults to `https://wallet.hiro.so` for the Stacks Wallet, which is handled by the Stacks Wallet browser extension if installed. | -## Deploy smart contract +-> Contracts will deploy to the Stacks address of the authenticated user. -To allow your app's users to deploy Clarity smart contracts, use the `openContractDeploy` method. +## Prompt to execute contract -```tsx -import { openContractDeploy } from '@blockstack/connect'; +Call the `openContractCall` function provided by the `connect` package to trigger the display of a transaction signing prompt for executing a contract: -const codeBody = '(begin (print "hello, world"))'; +```tsx +import { openContractCall } from '@stacks/connect'; -openContractDeploy({ - contractName: 'my-contract-name', - codeBody, +const options = { + contractAddress: 'ST22T6ZS7HVWEMZHHFK77H4GTNDTWNPQAX8WZAKHJ', + contractName: 'status', + functionName: 'write-status!', + functionArgs: [ + { + type: 'buff', + value: 'hello world', + }, + ], + authOrigin, appDetails: { - name: 'SuperApp', - icon: 'https://example.com/icon.png', + name: 'My App', + icon: window.location.origin + '/my-app-logo.svg', }, finished: data => { - console.log(data.txId); + console.log('Transaction ID:', data.txId); + console.log('Raw transaction:', data.txRaw); }, -}); +}; + +await openContractCall(options); ``` -Here is the interface for the options you can provide to `openContractDeploy`: +Several parameters are available for calling `openContractCall`. Here's the exact interface for them: ```tsx -interface ContractDeployOptions { - codeBody: string; +interface ContractCallOptions { + contractAddress: string; + functionName: string; contractName: string; + functionArgs?: any[]; authOrigin?: string; appDetails: { name: string; @@ -206,21 +183,56 @@ interface ContractDeployOptions { } ``` -| parameter | type | optional | description | -| ------------ | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| codeBody | string | false | The Clarity source code for this contract | -| contractName | string | false | The name for this contract | -| appDetails | object | false | A dictionary that includes `name` and `icon` | -| finished | function | false | A callback that is fired when the transaction is signed and broadcasted. Your callback will receive an object back with a `txId` and a `txRaw`, both of which are strings. | -| authOrigin | string | true | The location of the authenticator. This is only necessary when developing the authenticator locally, or when using beta features. Defaults to `"https://app.blockstack.org"`. | +| parameter | type | required | description | +| --------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| contractAddress | string | true | Stacks address to which contract is deployed | +| contractName | string | true | Name of contract to sign | +| functionName | string | true | Name of function for signing / execution, which needs to be a [public function](/references/language-functions#define-public). | +| functionArgs | array | true | Arguments for calling the function. [Provide the Clarity type with each argument](#passing-clarity-types-with-function-arguments). Defaults to `[]`. | +| appDetails | object | true | Dictionary that requires `name` and `icon` for app | +| finished | function | true | Callback executed by app when transaction has been signed and broadcasted. It received an object back with `txId` and `txRaw` properties, both of which are strings. | +| authOrigin | string | false | URL of authenticator to use for prompting signature and broadcast. Defaults to `https://wallet.hiro.so` for the Stacks Wallet, which is handled by the Stacks Wallet browser extension if installed. | + +### Passing Clarity types with function arguments + +To serialize your transaction properly, you'll need to provide an appropriate Clarity type for each function argument. + +These types are named the same as in Clarity and must be passed as strings: + +- `uint`: Unsigned integer (e.g. `"240"`) +- `int`: Signed integer (e.g. `"12"`) +- `bool`: Boolean (e.g. `true` or `false`, `0` or `1`) +- `buff`: Buffer (e.g. `"hello world"`) +- `principal`: [Contract or standard principal](/write-smart-contracts/principals) (e.g. `"ST22T6ZS7HVWEMZHHFK77H4GTNDTWNPQAX8WZAKHJ"`) or `"ST22T6ZS7HVWEMZHHFK77H4GTNDTWNPQAX8WZAKHJ.my-contract"`. + +Argument are provided in an array of objects with keys `type` and `value`: + +```tsx +const functionArguments = [ + { + type: 'buff', + value: 'hello, world', + }, + { + type: 'uint', + value: '1', + }, +]; +``` + +-> If you're using TypeScript, these Clarity types can be imported as `ContractCallArgumentType` from `@stacks/connect`. ## Usage in React Apps -Make sure you follow the [setup instructions](/authentication/building-todo-app#onboard-into-your-first-stacks-app) first. When you're using -`useConnect`, you don't have to specify `appDetails` - we'll pick that up from your existing configuration. +Import the `useConnect` from the `connect` package to integrate transaction signing more seamlessly into React apps. -Each transaction signing method is exposed through the `useConnect` hook, but they're prefixed with `do` instead of -`open`, to remain consistent with our React action naming standards. +Each transaction signing method is itself available as a function returned by `useConnect` though prefixed with `do` for consistency with React action naming standards: + +- `openContractCall` as `doContractCall` +- `openSTXTransfer` as `doSTXTransfer` +- `openContractDeploy` as `doContractDeploy` + +Use these functions with the same parameters as outlined above. However, you don't have to specify `appDetails` since they are detected automatically if `useConnect` has been used already for authentication. ```tsx import { useConnect } from '@stacks/connect'; @@ -239,8 +251,10 @@ const MyComponent = () => { }; ``` -## Network settings +## Change network + +TBD: Instructions for changing between mainnet, testnet and local networks -TBD: instructions on toggling network +## Request testnet STX from faucet -You may find it useful to request testnet STX from [the faucet](https://testnet.blockstack.org/faucet) while developing and testing your app with the Stacks testnet. +You may find it useful to request testnet STX from [the faucet](https://testnet.blockstack.org/faucet) while developing your app with the Stacks testnet.