-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
307 additions
and
21 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import styled from 'styled-components'; | ||
|
||
export const ErrorMessage = styled.div({ | ||
color: 'red', | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { Button, Card, Checkbox, Stack, Switch } from '@mantine/core'; | ||
import { useMutation } from '@tanstack/react-query'; | ||
import { useState } from 'react'; | ||
import { ErrorMessage } from '../../common'; | ||
import { mutationFunction } from './mutationFunction'; | ||
|
||
export interface Props { | ||
publicKey: string; | ||
} | ||
|
||
function buttonText(isPending: boolean) { | ||
return isPending ? 'Signing transactions...' : 'Sign transactions'; | ||
} | ||
|
||
export function SignTransactions({ publicKey }: Props) { | ||
// Checkboxes | ||
const [isPoolAllowContractSelected, setIsPoolAllowContractSelected] = useState(false); | ||
const [isPoolDelegateStacksSelected, setIsPoolDelegateStacks] = useState(false); | ||
const [isContractDeploySelected, setIsContractDeploySelected] = useState(false); | ||
const [isTokenTransferSelected, setIsTokenTransferSelected] = useState(false); | ||
|
||
const [broadcast, setBroadcast] = useState(true); | ||
|
||
const signTransactionsMutation = useMutation({ | ||
mutationFn: mutationFunction, | ||
}); | ||
|
||
function handleSignTransactionsClick() { | ||
signTransactionsMutation | ||
.mutateAsync({ | ||
isPoolAllowContractSelected, | ||
isPoolDelegateStacksSelected, | ||
isContractDeploySelected, | ||
isTokenTransferSelected, | ||
broadcast, | ||
publicKey, | ||
}) | ||
.then(console.log) | ||
.catch((error: unknown) => { | ||
console.error(error); | ||
if (error instanceof Error) console.error(error.cause); | ||
}); | ||
} | ||
|
||
return ( | ||
<Card> | ||
<h3>Sign transactions</h3> | ||
<Stack> | ||
<Checkbox | ||
label="Pool Allow Contract" | ||
checked={isPoolAllowContractSelected} | ||
onChange={() => setIsPoolAllowContractSelected(!isPoolAllowContractSelected)} | ||
/> | ||
<Checkbox | ||
label="Pool Delegate Stacks" | ||
checked={isPoolDelegateStacksSelected} | ||
onChange={() => setIsPoolDelegateStacks(!isPoolDelegateStacksSelected)} | ||
/> | ||
<Checkbox | ||
label="Contract Deploy" | ||
checked={isContractDeploySelected} | ||
onChange={() => setIsContractDeploySelected(!isContractDeploySelected)} | ||
/> | ||
<Checkbox | ||
label="Token Transfer" | ||
checked={isTokenTransferSelected} | ||
onChange={() => setIsTokenTransferSelected(!isTokenTransferSelected)} | ||
/> | ||
<Switch label="Broadcast" checked={broadcast} onChange={() => setBroadcast(!broadcast)} /> | ||
|
||
<Button onClick={handleSignTransactionsClick} disabled={signTransactionsMutation.isPending}> | ||
{buttonText(signTransactionsMutation.isPending)} | ||
</Button> | ||
|
||
{signTransactionsMutation.isError && !signTransactionsMutation.isPending && ( | ||
<ErrorMessage>Failed to sign transactions. Check console for details.</ErrorMessage> | ||
)} | ||
</Stack> | ||
</Card> | ||
); | ||
} |
111 changes: 111 additions & 0 deletions
111
example/src/components/stacks/SignTransactions/mutationFunction.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { request } from '@sats-connect/core'; | ||
import { poxAddressToTuple } from '@stacks/stacking'; | ||
import { | ||
contractPrincipalCV, | ||
makeUnsignedContractCall, | ||
makeUnsignedContractDeploy, | ||
makeUnsignedSTXTokenTransfer, | ||
noneCV, | ||
standardPrincipalCV, | ||
uintCV, | ||
} from '@stacks/transactions'; | ||
|
||
const helloWorldContractBody = ` | ||
(define-data-var greeting (string-ascii 100) "Hello, World!") | ||
(define-read-only (get-greeting) | ||
(ok (var-get greeting)) | ||
) | ||
(define-public (set-greeting (new-greeting (string-ascii 100))) | ||
(begin | ||
(var-set greeting new-greeting) | ||
(ok new-greeting)) | ||
) | ||
`; | ||
|
||
export const poxContractAddress = 'SP000000000000000000002Q6VF78'; | ||
export const poxContractName = 'pox-4'; | ||
export const poolContractAddress = 'SP001SFSMC2ZY76PD4M68P3WGX154XCH7NE3TYMX'; | ||
export const poolContractName = 'pox4-pools'; | ||
export const poolAdminStacksAddress = 'SPXVRSEH2BKSXAEJ00F1BY562P45D5ERPSKR4Q33'; | ||
export const poolAdminPoxAddress = 'bc1qmv2pxw5ahvwsu94kq5f520jgkmljs3af8ly6tr'; | ||
|
||
export interface MutationFnArgs { | ||
isPoolAllowContractSelected: boolean; | ||
isPoolDelegateStacksSelected: boolean; | ||
isContractDeploySelected: boolean; | ||
isTokenTransferSelected: boolean; | ||
broadcast: boolean; | ||
publicKey: string; | ||
} | ||
|
||
export async function mutationFunction({ | ||
isPoolAllowContractSelected, | ||
isPoolDelegateStacksSelected, | ||
isContractDeploySelected, | ||
isTokenTransferSelected, | ||
broadcast, | ||
publicKey, | ||
}: MutationFnArgs) { | ||
const transactions: string[] = []; | ||
|
||
if (isPoolAllowContractSelected) { | ||
const transaction = await makeUnsignedContractCall({ | ||
contractAddress: poxContractAddress, | ||
contractName: poxContractName, | ||
functionName: 'allow-contract-caller', | ||
functionArgs: [contractPrincipalCV(poolContractAddress, poolContractName), noneCV()], | ||
publicKey, | ||
}); | ||
transactions.push(transaction.serialize()); | ||
} | ||
|
||
if (isPoolDelegateStacksSelected) { | ||
const transaction = await makeUnsignedContractCall({ | ||
contractAddress: poolContractAddress, | ||
contractName: poolContractName, | ||
functionName: 'delegate-stx', | ||
functionArgs: [ | ||
uintCV(1234567890), | ||
standardPrincipalCV(poolAdminStacksAddress), | ||
noneCV(), | ||
noneCV(), | ||
poxAddressToTuple(poolAdminPoxAddress), | ||
noneCV(), | ||
], | ||
publicKey, | ||
}); | ||
transactions.push(transaction.serialize()); | ||
} | ||
|
||
if (isContractDeploySelected) { | ||
const now = new Date().getTime(); | ||
const transaction = await makeUnsignedContractDeploy({ | ||
contractName: `hello-world-${now}`, | ||
codeBody: helloWorldContractBody, | ||
publicKey, | ||
}); | ||
transactions.push(transaction.serialize()); | ||
} | ||
|
||
if (isTokenTransferSelected) { | ||
const transaction = await makeUnsignedSTXTokenTransfer({ | ||
recipient: 'SP1VYV2JBF1QPNDSKHBZRAWRC4KQXP8ZSSRNKPJE4', // acc 4 | ||
amount: '100000', // 0.1 STX | ||
publicKey, | ||
}); | ||
transactions.push(transaction.serialize()); | ||
} | ||
|
||
const res = await request('stx_signTransactions', { | ||
transactions, | ||
broadcast, | ||
}); | ||
|
||
if (res.status === 'error') { | ||
throw new Error('Error signing transactions', { cause: res.error }); | ||
} | ||
|
||
return res.result; | ||
} |
Oops, something went wrong.