diff --git a/.changeset/hungry-monkeys-wonder.md b/.changeset/hungry-monkeys-wonder.md new file mode 100644 index 000000000..dbf6aa213 --- /dev/null +++ b/.changeset/hungry-monkeys-wonder.md @@ -0,0 +1,7 @@ +--- +'@siafoundation/walletd-js': minor +'@siafoundation/walletd-react': minor +'@siafoundation/walletd-types': minor +--- + +Added construct APIs for both v1 and v2 transactions. diff --git a/.changeset/perfect-turtles-kiss.md b/.changeset/perfect-turtles-kiss.md new file mode 100644 index 000000000..75a64a9a0 --- /dev/null +++ b/.changeset/perfect-turtles-kiss.md @@ -0,0 +1,7 @@ +--- +'@siafoundation/walletd-js': minor +'@siafoundation/walletd-react': minor +'@siafoundation/walletd-types': minor +--- + +Added the basis ChainIndex parameter to txpool broadcast API. diff --git a/.changeset/tiny-deers-wink.md b/.changeset/tiny-deers-wink.md new file mode 100644 index 000000000..4d78cd964 --- /dev/null +++ b/.changeset/tiny-deers-wink.md @@ -0,0 +1,7 @@ +--- +'@siafoundation/walletd-js': minor +'@siafoundation/walletd-react': minor +'@siafoundation/walletd-types': minor +--- + +Added the basis ChainIndex parameter to fund APIs. diff --git a/.changeset/tricky-carrots-deny.md b/.changeset/tricky-carrots-deny.md new file mode 100644 index 000000000..6fba0fa3f --- /dev/null +++ b/.changeset/tricky-carrots-deny.md @@ -0,0 +1,7 @@ +--- +'@siafoundation/walletd-js': minor +'@siafoundation/walletd-react': minor +'@siafoundation/walletd-types': minor +--- + +Added the basis ChainIndex value to txpool transactions response. diff --git a/apps/walletd/contexts/addresses/dataset.tsx b/apps/walletd/contexts/addresses/dataset.tsx index d9d95f1ff..9af2c7fc6 100644 --- a/apps/walletd/contexts/addresses/dataset.tsx +++ b/apps/walletd/contexts/addresses/dataset.tsx @@ -19,8 +19,8 @@ export function transformAddressesResponse( const datum: AddressData = { id: address, address, - description: description, - spendPolicy: spendPolicy, + description, + spendPolicy, metadata: (metadata || {}) as WalletAddressMetadata, walletId, onClick: () => diff --git a/apps/walletd/contexts/addresses/types.ts b/apps/walletd/contexts/addresses/types.ts index 7f2ed661d..4eee497a9 100644 --- a/apps/walletd/contexts/addresses/types.ts +++ b/apps/walletd/contexts/addresses/types.ts @@ -2,6 +2,7 @@ import { WalletAddress, WalletAddressMetadata, } from '@siafoundation/walletd-types' +import { SpendPolicy } from '@siafoundation/types' export type CellContext = { siascanUrl: string @@ -11,7 +12,7 @@ export type AddressData = { id: string address: string description?: string - spendPolicy?: string + spendPolicy?: SpendPolicy metadata: WalletAddressMetadata walletId: string raw?: WalletAddress diff --git a/apps/walletd/dialogs/WalletSendLedgerDialog/useFundAndSign.tsx b/apps/walletd/dialogs/WalletSendLedgerDialog/useFundAndSign.tsx index 91ec45d09..9c9598671 100644 --- a/apps/walletd/dialogs/WalletSendLedgerDialog/useFundAndSign.tsx +++ b/apps/walletd/dialogs/WalletSendLedgerDialog/useFundAndSign.tsx @@ -1,4 +1,4 @@ -import { Transaction } from '@siafoundation/types' +import { ChainIndex, Transaction } from '@siafoundation/types' import { useCallback } from 'react' import { SendParams } from '../_sharedWalletSend/types' @@ -7,6 +7,7 @@ type Props = { fundedTransaction?: Transaction toSign?: string[] error?: string + basis?: ChainIndex }> cancel: (transaction: Transaction) => Promise sign: ({ @@ -28,6 +29,7 @@ export function useFundAndSign({ fund, cancel, sign }: Props) { fundedTransaction, toSign, error: fundingError, + basis, } = await fund(params) if (fundingError) { return { @@ -47,6 +49,7 @@ export function useFundAndSign({ fund, cancel, sign }: Props) { } } return { + basis, signedTransaction, } }, diff --git a/apps/walletd/dialogs/WalletSendLedgerDialog/useSendForm.tsx b/apps/walletd/dialogs/WalletSendLedgerDialog/useSendForm.tsx index 24c375351..b30549e36 100644 --- a/apps/walletd/dialogs/WalletSendLedgerDialog/useSendForm.tsx +++ b/apps/walletd/dialogs/WalletSendLedgerDialog/useSendForm.tsx @@ -10,7 +10,7 @@ import { } from '@siafoundation/design-system' import { DeviceConnectForm } from '../DeviceConnectForm' import { useLedger } from '../../contexts/ledger' -import { Transaction } from '@siafoundation/types' +import { Transaction, ChainIndex } from '@siafoundation/types' import { LedgerSignTxn } from './LedgerSignTxn' import { useSign } from './useSign' import { useBroadcast } from '../_sharedWalletSend/useBroadcast' @@ -69,10 +69,12 @@ export function useSendForm({ params, step, onConfirm }: Props) { const fundAndSign = useFundAndSign({ cancel, fund, sign }) const [waitingForUser, setWaitingForUser] = useState(false) const [txn, setTxn] = useState() + const [basis, setBasis] = useState() useEffect(() => { if (step === 'compose') { setTxn(undefined) + setBasis(undefined) } }, [step]) @@ -109,8 +111,17 @@ export function useSendForm({ params, step, onConfirm }: Props) { return } + if (!txn) { + return + } + + if (!basis) { + return + } + const { error } = await broadcast({ signedTransaction: txn, + basis, }) if (error) { @@ -124,7 +135,7 @@ export function useSendForm({ params, step, onConfirm }: Props) { // transactionId, }) }, - [broadcast, txn, onConfirm] + [broadcast, txn, basis, onConfirm] ) const onInvalid = useOnInvalid(fields) @@ -136,11 +147,12 @@ export function useSendForm({ params, step, onConfirm }: Props) { const runFundAndSign = useCallback(async () => { setWaitingForUser(true) - const { signedTransaction, error } = await fundAndSign(params) + const { signedTransaction, error, basis } = await fundAndSign(params) if (error) { triggerErrorToast({ title: error }) } else { setTxn(signedTransaction) + setBasis(basis) form.setValue('isSigned', true) } setWaitingForUser(false) diff --git a/apps/walletd/dialogs/WalletSendSeedDialog/useSignAndBroadcast.tsx b/apps/walletd/dialogs/WalletSendSeedDialog/useSignAndBroadcast.tsx index dbf71af8b..c49676d91 100644 --- a/apps/walletd/dialogs/WalletSendSeedDialog/useSignAndBroadcast.tsx +++ b/apps/walletd/dialogs/WalletSendSeedDialog/useSignAndBroadcast.tsx @@ -49,6 +49,7 @@ export function useSignAndBroadcast() { fundedTransaction, toSign, error: fundingError, + basis, } = await fund(params) if (fundingError) { return { @@ -77,7 +78,7 @@ export function useSignAndBroadcast() { cacheWalletMnemonic(walletId, mnemonic) // broadcast - return broadcast({ signedTransaction }) + return broadcast({ signedTransaction, basis }) }, [ cancel, diff --git a/apps/walletd/dialogs/_sharedWalletSend/useBroadcast.tsx b/apps/walletd/dialogs/_sharedWalletSend/useBroadcast.tsx index 6d2ba1cc3..1497e998f 100644 --- a/apps/walletd/dialogs/_sharedWalletSend/useBroadcast.tsx +++ b/apps/walletd/dialogs/_sharedWalletSend/useBroadcast.tsx @@ -1,4 +1,4 @@ -import { Transaction } from '@siafoundation/types' +import { Transaction, ChainIndex } from '@siafoundation/types' import { useTxPoolBroadcast } from '@siafoundation/walletd-react' import { useCallback } from 'react' @@ -6,7 +6,13 @@ export function useBroadcast({ cancel }: { cancel: (t: Transaction) => void }) { const txPoolBroadcast = useTxPoolBroadcast() const broadcast = useCallback( - async ({ signedTransaction }: { signedTransaction: Transaction }) => { + async ({ + signedTransaction, + basis, + }: { + signedTransaction: Transaction + basis: ChainIndex + }) => { if (!signedTransaction) { return { error: 'No signed transaction', @@ -15,6 +21,7 @@ export function useBroadcast({ cancel }: { cancel: (t: Transaction) => void }) { // broadcast const broadcastResponse = await txPoolBroadcast.post({ payload: { + basis, transactions: [signedTransaction], v2transactions: [], }, diff --git a/apps/walletd/dialogs/_sharedWalletSend/useFund.tsx b/apps/walletd/dialogs/_sharedWalletSend/useFund.tsx index 4077756b2..3b6d03138 100644 --- a/apps/walletd/dialogs/_sharedWalletSend/useFund.tsx +++ b/apps/walletd/dialogs/_sharedWalletSend/useFund.tsx @@ -54,6 +54,7 @@ export function useFund() { } } return { + basis: fundResponse.data.basis, fundedTransaction: fundResponse.data.transaction, toSign: fundResponse.data.toSign, } @@ -103,6 +104,7 @@ export function useFund() { } toSign.push(...fundResponse.data.toSign) return { + basis: fundResponse.data.basis, fundedTransaction: fundResponse.data.transaction, toSign, } diff --git a/apps/walletd/lib/signLedger.spec.ts b/apps/walletd/lib/signLedger.spec.ts index 06336b748..4ab745ccb 100644 --- a/apps/walletd/lib/signLedger.spec.ts +++ b/apps/walletd/lib/signLedger.spec.ts @@ -17,8 +17,8 @@ describe('signLedger', () => { device, transaction: mocks.walletFundResponse.transaction, toSign: mocks.walletFundResponse.toSign, - siacoinOutputs: mocks.walletOutputsSiacoinResponse, - siafundOutputs: mocks.walletOutputsSiafundResponse, + siacoinOutputs: mocks.walletOutputsSiacoinResponse.outputs, + siafundOutputs: mocks.walletOutputsSiafundResponse.outputs, addresses: getMockAddresses(mocks), }) ).toMatchSnapshot() @@ -31,8 +31,8 @@ describe('signLedger', () => { await signTransactionLedger({ device, transaction: mocks.walletFundResponse.transaction, - siacoinOutputs: mocks.walletOutputsSiacoinResponse, - siafundOutputs: mocks.walletOutputsSiafundResponse, + siacoinOutputs: mocks.walletOutputsSiacoinResponse.outputs, + siafundOutputs: mocks.walletOutputsSiafundResponse.outputs, addresses: getMockAddresses(mocks), toSign: [mocks.walletFundResponse.toSign[0], 'not in siacoinOutputs'], }) @@ -49,8 +49,8 @@ describe('signLedger', () => { device, transaction: mocks.walletFundResponse.transaction, toSign: mocks.walletFundResponse.toSign, - siacoinOutputs: mocks.walletOutputsSiacoinResponse, - siafundOutputs: mocks.walletOutputsSiafundResponse, + siacoinOutputs: mocks.walletOutputsSiacoinResponse.outputs, + siafundOutputs: mocks.walletOutputsSiafundResponse.outputs, addresses: [ { id: 'id', @@ -75,14 +75,15 @@ describe('signLedger', () => { device, transaction: mocks.walletFundResponse.transaction, toSign: mocks.walletFundResponse.toSign, - siacoinOutputs: mocks.walletOutputsSiacoinResponse, - siafundOutputs: mocks.walletOutputsSiafundResponse, + siacoinOutputs: mocks.walletOutputsSiacoinResponse.outputs, + siafundOutputs: mocks.walletOutputsSiafundResponse.outputs, addresses: [ { id: 'id', walletId: 'id', address: - mocks.walletOutputsSiacoinResponse[1].siacoinOutput.address, + mocks.walletOutputsSiacoinResponse.outputs[1].siacoinOutput + .address, metadata: {}, }, ], @@ -102,8 +103,8 @@ describe('signLedger', () => { device, transaction: mocks.walletFundResponse.transaction, toSign: mocks.walletFundResponse.toSign, - siacoinOutputs: mocks.walletOutputsSiacoinResponse, - siafundOutputs: mocks.walletOutputsSiafundResponse, + siacoinOutputs: mocks.walletOutputsSiacoinResponse.outputs, + siafundOutputs: mocks.walletOutputsSiafundResponse.outputs, addresses, }) ).toEqual({ diff --git a/apps/walletd/lib/signSeed.spec.ts b/apps/walletd/lib/signSeed.spec.ts index b6e05d5fa..fccd46874 100644 --- a/apps/walletd/lib/signSeed.spec.ts +++ b/apps/walletd/lib/signSeed.spec.ts @@ -17,8 +17,8 @@ describe('signSeed', () => { toSign: mocks.walletFundResponse.toSign, consensusState: mocks.consensusState, consensusNetwork: mocks.consensusNetwork, - siacoinOutputs: mocks.walletOutputsSiacoinResponse, - siafundOutputs: mocks.walletOutputsSiafundResponse, + siacoinOutputs: mocks.walletOutputsSiacoinResponse.outputs, + siafundOutputs: mocks.walletOutputsSiafundResponse.outputs, addresses: getMockAddresses(mocks), }) ).toMatchSnapshot() @@ -32,8 +32,8 @@ describe('signSeed', () => { transaction: mocks.walletFundResponse.transaction, consensusState: mocks.consensusState, consensusNetwork: mocks.consensusNetwork, - siacoinOutputs: mocks.walletOutputsSiacoinResponse, - siafundOutputs: mocks.walletOutputsSiafundResponse, + siacoinOutputs: mocks.walletOutputsSiacoinResponse.outputs, + siafundOutputs: mocks.walletOutputsSiafundResponse.outputs, addresses: getMockAddresses(mocks), toSign: ['not in siacoinOutputs'], }) @@ -51,8 +51,8 @@ describe('signSeed', () => { toSign: mocks.walletFundResponse.toSign, consensusState: mocks.consensusState, consensusNetwork: mocks.consensusNetwork, - siacoinOutputs: mocks.walletOutputsSiacoinResponse, - siafundOutputs: mocks.walletOutputsSiafundResponse, + siacoinOutputs: mocks.walletOutputsSiacoinResponse.outputs, + siafundOutputs: mocks.walletOutputsSiafundResponse.outputs, addresses: [ { id: 'id', @@ -78,8 +78,8 @@ describe('signSeed', () => { toSign: mocks.walletFundResponse.toSign, consensusState: mocks.consensusState, consensusNetwork: mocks.consensusNetwork, - siacoinOutputs: mocks.walletOutputsSiacoinResponse, - siafundOutputs: mocks.walletOutputsSiafundResponse, + siacoinOutputs: mocks.walletOutputsSiacoinResponse.outputs, + siafundOutputs: mocks.walletOutputsSiafundResponse.outputs, addresses: [ { id: 'id', @@ -106,8 +106,8 @@ describe('signSeed', () => { toSign: mocks.walletFundResponse.toSign, consensusState: mocks.consensusState, consensusNetwork: mocks.consensusNetwork, - siacoinOutputs: mocks.walletOutputsSiacoinResponse, - siafundOutputs: mocks.walletOutputsSiafundResponse, + siacoinOutputs: mocks.walletOutputsSiacoinResponse.outputs, + siafundOutputs: mocks.walletOutputsSiafundResponse.outputs, addresses, }) ).toEqual({ diff --git a/libs/types/src/v2.ts b/libs/types/src/v2.ts index 3d613a5a2..0b5c17d9a 100644 --- a/libs/types/src/v2.ts +++ b/libs/types/src/v2.ts @@ -11,9 +11,13 @@ import { SiafundOutput, Signature, StateElement, + UnlockConditions, } from './core' -export type SpendPolicy = string +export type SpendPolicy = { + type: 'uc' + policy: UnlockConditions +} export type V2SiacoinInput = { parent: SiacoinElement diff --git a/libs/walletd-js/src/index.ts b/libs/walletd-js/src/index.ts index 87cb5dd73..dee23fc93 100644 --- a/libs/walletd-js/src/index.ts +++ b/libs/walletd-js/src/index.ts @@ -47,6 +47,12 @@ import { WalletBalanceParams, WalletBalancePayload, WalletBalanceResponse, + WalletConstructV1TransactionParams, + WalletConstructV1TransactionPayload, + WalletConstructV1TransactionResponse, + WalletConstructV2TransactionParams, + WalletConstructV2TransactionPayload, + WalletConstructV2TransactionResponse, WalletDeleteParams, WalletDeletePayload, WalletDeleteResponse, @@ -93,6 +99,8 @@ import { walletsIdAddressesAddrRoute, walletsIdAddressesRoute, walletsIdBalanceRoute, + walletsIdConstructTransactionRoute, + walletsIdConstructV2TransactionRoute, walletsIdEventsRoute, walletsIdEventsUnconfirmedRoute, walletsIdFundRoute, @@ -245,5 +253,15 @@ export function Walletd({ api, password }: { api: string; password?: string }) { WalletReleasePayload, WalletReleaseResponse >(axios, 'post', walletsIdReleaseRoute), + walletConstructV1Transaction: buildRequestHandler< + WalletConstructV1TransactionParams, + WalletConstructV1TransactionPayload, + WalletConstructV1TransactionResponse + >(axios, 'post', walletsIdConstructTransactionRoute), + walletConstructV2Transaction: buildRequestHandler< + WalletConstructV2TransactionParams, + WalletConstructV2TransactionPayload, + WalletConstructV2TransactionResponse + >(axios, 'post', walletsIdConstructV2TransactionRoute), } } diff --git a/libs/walletd-mock/src/scenarios/seedWallet.ts b/libs/walletd-mock/src/scenarios/seedWallet.ts index 9b0a6e380..05bd4304f 100644 --- a/libs/walletd-mock/src/scenarios/seedWallet.ts +++ b/libs/walletd-mock/src/scenarios/seedWallet.ts @@ -1,9 +1,11 @@ -import { SiacoinElement, SiafundElement } from '@siafoundation/types' import { Wallet, WalletAddress, WalletBalanceResponse, + WalletConstructV2TransactionResponse, WalletFundSiacoinResponse, + WalletOutputsSiacoinResponse, + WalletOutputsSiafundResponse, } from '@siafoundation/walletd-types' import { toHastings } from '@siafoundation/units' import { getMockConsensusNetworkResponse } from '../mocks/consensusNetwork' @@ -37,53 +39,69 @@ export function getMockScenarioSeedWallet() { siafunds: 10, } - const walletOutputsSiacoinResponse: SiacoinElement[] = [ - { - id: 'aa3e781330c9b3991e0141807df1327fadf114ca6c37acb9e58004f942d91dfb', - leafIndex: 304248, - merkleProof: [ - '0a7a4c392f78899e3c38c5cd9e6a673b2c7afec97930af539af9c8e20209aa78', - 'a1e074dc48634a234b7366a0d7ab19cd05e3e698e1d44bf07e24d75ae0c65b3c', - '44d107342962e2068d289ce090c87b7bf0c847f734bdfad10db5546e402c3ad7', - '64ea3e65ecd5ebc1c0ce014673148060855ce550571208b6303b8e2a83e33451', - '19e37bf7747c6d8c7b87d2474dbbd3a8f5b26d89642f8e1af4b9b02abdfb2ea6', - '1fc2ac9f70211a3be6f334db14feb8b327458aee49d3539770640cbdec9b4a5f', - 'defbbc18c64349f11e75537955861ececce0fadf10baec456f6c74b024820af1', - '87d27ff868ca3b1dce59ae754eaec48239718e81e2e6f3b7b418f5a00362bcf7', - '93d823c55fbd09de462a8e355921433b3693d63de58ea8e2780a2c2ffabd0fee', - 'a68820d6b79b2735b15c69d0fc26b11252bb27f22b9088559ed13f9420f5dda1', - '1bbcead690290291ea9628214a121ef783411693975171803bf5716a3a6ff19b', - ], - siacoinOutput: { - value: '1000000000000000000000000', - address: - 'f2dbf56b5b0c698d7fbf43f646c76169d84e597e8b37fada97348beeecaa812d400ac4ce7981', - }, - maturityHeight: 0, + const walletOutputsSiacoinResponse: WalletOutputsSiacoinResponse = { + basis: { + height: 0, + id: '0', }, - { - id: '32e430158591b4073a6834e9f4c4b67162e348844f569f4e472896bb72efb724', - leafIndex: 305723, - merkleProof: [ - '8c02aeec48de589ce497ebe72fb8b527cfe022ef513fcfdc56745c84832f00ec', - '1bf63b9959e60272fd7a48a8cecd4120a852c0e14557ea27ccad6ea2071e70b3', - '21b7e1606e9fd677059c58a1a687682182f71ce09e071431dcaff823a3a5d49e', - 'e81ac37d3b4db6166dc1bb10ebfa49f57cbf99aababd36ee4e3e5e12082dc6dc', - 'ecc307c6c3e505d97ccf821938e5e5702ef0130d33c991ca95735f7d9706a4b8', - '9560060ee399793f102e092afdfdbdd33692706256955e8390af552de0addfc0', - ], - siacoinOutput: { - value: '97988210000000000000000000', - address: - 'f2dbf56b5b0c698d7fbf43f646c76169d84e597e8b37fada97348beeecaa812d400ac4ce7981', + outputs: [ + { + id: 'aa3e781330c9b3991e0141807df1327fadf114ca6c37acb9e58004f942d91dfb', + leafIndex: 304248, + merkleProof: [ + '0a7a4c392f78899e3c38c5cd9e6a673b2c7afec97930af539af9c8e20209aa78', + 'a1e074dc48634a234b7366a0d7ab19cd05e3e698e1d44bf07e24d75ae0c65b3c', + '44d107342962e2068d289ce090c87b7bf0c847f734bdfad10db5546e402c3ad7', + '64ea3e65ecd5ebc1c0ce014673148060855ce550571208b6303b8e2a83e33451', + '19e37bf7747c6d8c7b87d2474dbbd3a8f5b26d89642f8e1af4b9b02abdfb2ea6', + '1fc2ac9f70211a3be6f334db14feb8b327458aee49d3539770640cbdec9b4a5f', + 'defbbc18c64349f11e75537955861ececce0fadf10baec456f6c74b024820af1', + '87d27ff868ca3b1dce59ae754eaec48239718e81e2e6f3b7b418f5a00362bcf7', + '93d823c55fbd09de462a8e355921433b3693d63de58ea8e2780a2c2ffabd0fee', + 'a68820d6b79b2735b15c69d0fc26b11252bb27f22b9088559ed13f9420f5dda1', + '1bbcead690290291ea9628214a121ef783411693975171803bf5716a3a6ff19b', + ], + siacoinOutput: { + value: '1000000000000000000000000', + address: + 'f2dbf56b5b0c698d7fbf43f646c76169d84e597e8b37fada97348beeecaa812d400ac4ce7981', + }, + maturityHeight: 0, }, - maturityHeight: 0, - }, - ] + { + id: '32e430158591b4073a6834e9f4c4b67162e348844f569f4e472896bb72efb724', + leafIndex: 305723, + merkleProof: [ + '8c02aeec48de589ce497ebe72fb8b527cfe022ef513fcfdc56745c84832f00ec', + '1bf63b9959e60272fd7a48a8cecd4120a852c0e14557ea27ccad6ea2071e70b3', + '21b7e1606e9fd677059c58a1a687682182f71ce09e071431dcaff823a3a5d49e', + 'e81ac37d3b4db6166dc1bb10ebfa49f57cbf99aababd36ee4e3e5e12082dc6dc', + 'ecc307c6c3e505d97ccf821938e5e5702ef0130d33c991ca95735f7d9706a4b8', + '9560060ee399793f102e092afdfdbdd33692706256955e8390af552de0addfc0', + ], + siacoinOutput: { + value: '97988210000000000000000000', + address: + 'f2dbf56b5b0c698d7fbf43f646c76169d84e597e8b37fada97348beeecaa812d400ac4ce7981', + }, + maturityHeight: 0, + }, + ], + } - const walletOutputsSiafundResponse: SiafundElement[] = [] + const walletOutputsSiafundResponse: WalletOutputsSiafundResponse = { + basis: { + height: 0, + id: '0', + }, + outputs: [], + } const walletFundResponse: WalletFundSiacoinResponse = { + basis: { + height: 0, + id: '0', + }, transaction: { siacoinInputs: [ { @@ -126,6 +144,84 @@ export function getMockScenarioSeedWallet() { dependsOn: null, } + const walletConstructV2Response: WalletConstructV2TransactionResponse = { + id: '0', + basis: { + height: 0, + id: '0', + }, + transaction: { + siacoinInputs: [ + { + parent: { + id: 'aa3e781330c9b3991e0141807df1327fadf114ca6c37acb9e58004f942d91dfb', + maturityHeight: 0, + siacoinOutput: { + value: '1000000000000000000000000', + address: + '90c6057cdd2463eca61f83796e83152dbba28b6cb9a74831a043833051ec9f422726bfff2ee8', + }, + leafIndex: 304248, + merkleProof: [ + '0a7a4c392f78899e3c38c5cd9e6a673b2c7afec97930af539af9c8e20209aa78', + 'a1e074dc48634a234b7366a0d7ab19cd05e3e698e1d44bf07e24d75ae0c65b3c', + ], + }, + satisfiedPolicy: { + policy: { + type: 'uc', + policy: { + timelock: 0, + publicKeys: null, + signaturesRequired: 1, + }, + }, + }, + }, + { + parent: { + id: '32e430158591b4073a6834e9f4c4b67162e348844f569f4e472896bb72efb724', + maturityHeight: 0, + siacoinOutput: { + value: '97984280000000000000000000', + address: + 'f2dbf56b5b0c698d7fbf43f646c76169d84e597e8b37fada97348beeecaa812d400ac4ce7981', + }, + leafIndex: 305723, + merkleProof: [ + '8c02aeec48de589ce497ebe72fb8b527cfe022ef513fcfdc56745c84832f00ec', + '1bf63b9959e60272fd7a48a8cecd4120a852c0e14557ea27ccad6ea2071e70b3', + ], + }, + satisfiedPolicy: { + policy: { + type: 'uc', + policy: { + timelock: 0, + publicKeys: null, + signaturesRequired: 1, + }, + }, + }, + }, + ], + siacoinOutputs: [ + { + value: '1000000000000000000000000', + address: + '90c6057cdd2463eca61f83796e83152dbba28b6cb9a74831a043833051ec9f422726bfff2ee8', + }, + { + value: '97984280000000000000000000', + address: + 'f2dbf56b5b0c698d7fbf43f646c76169d84e597e8b37fada97348beeecaa812d400ac4ce7981', + }, + ], + minerFee: '3930000000000000000000', + }, + estimatedFee: '0', + } + const walletAddressesResponse: WalletAddress[] = [ { address: @@ -185,6 +281,7 @@ export function getMockScenarioSeedWallet() { walletOutputsSiacoinResponse, walletOutputsSiafundResponse, walletFundResponse, + walletConstructV2Response, walletAddressesResponse, } } diff --git a/libs/walletd-react/src/api.ts b/libs/walletd-react/src/api.ts index e81660ce4..8a43cad0a 100644 --- a/libs/walletd-react/src/api.ts +++ b/libs/walletd-react/src/api.ts @@ -51,6 +51,12 @@ import { WalletAddressesResponse, WalletBalanceParams, WalletBalanceResponse, + WalletConstructV1TransactionParams, + WalletConstructV1TransactionPayload, + WalletConstructV1TransactionResponse, + WalletConstructV2TransactionParams, + WalletConstructV2TransactionPayload, + WalletConstructV2TransactionResponse, WalletDeleteParams, WalletDeletePayload, WalletDeleteResponse, @@ -92,6 +98,8 @@ import { walletsIdAddressesAddrRoute, walletsIdAddressesRoute, walletsIdBalanceRoute, + walletsIdConstructTransactionRoute, + walletsIdConstructV2TransactionRoute, walletsIdEventsRoute, walletsIdEventsUnconfirmedRoute, walletsIdFundRoute, @@ -460,3 +468,23 @@ export function useWalletRelease( ) { return usePostFunc({ ...args, route: walletsIdReleaseRoute }) } + +export function useWalletConstructV1Transaction( + args?: HookArgsCallback< + WalletConstructV1TransactionParams, + WalletConstructV1TransactionPayload, + WalletConstructV1TransactionResponse + > +) { + return usePostFunc({ ...args, route: walletsIdConstructTransactionRoute }) +} + +export function useWalletConstructV2Transaction( + args?: HookArgsCallback< + WalletConstructV2TransactionParams, + WalletConstructV2TransactionPayload, + WalletConstructV2TransactionResponse + > +) { + return usePostFunc({ ...args, route: walletsIdConstructV2TransactionRoute }) +} diff --git a/libs/walletd-types/src/api.ts b/libs/walletd-types/src/api.ts index 6dc9eaac0..6c12b98db 100644 --- a/libs/walletd-types/src/api.ts +++ b/libs/walletd-types/src/api.ts @@ -11,6 +11,10 @@ import { Transaction, V2Transaction, WalletEvent, + SiacoinOutput, + Address, + SiafundOutput, + TransactionID, } from '@siafoundation/types' import { GatewayPeer, Wallet, WalletAddress, WalletMetadata } from './types' @@ -37,6 +41,10 @@ export const walletsIdFundRoute = '/wallets/:id/fund' export const walletsIdFundSfRoute = '/wallets/:id/fundsf' export const walletsIdReserveRoute = '/wallets/:id/reserve' export const walletsIdReleaseRoute = '/wallets/:id/release' +export const walletsIdConstructTransactionRoute = + '/wallets/:id/construct/transaction' +export const walletsIdConstructV2TransactionRoute = + '/wallets/:id/construct/v2/transaction' // state @@ -79,6 +87,7 @@ export type SyncerConnectResponse = never export type TxPoolTransactionsParams = void export type TxPoolTransactionsPayload = void export type TxPoolTransactionsResponse = { + basis: ChainIndex transactions: Transaction[] v2transactions: V2Transaction[] } @@ -89,6 +98,7 @@ export type TxPoolFeeResponse = Currency export type TxPoolBroadcastParams = void export type TxPoolBroadcastPayload = { + basis: ChainIndex transactions: Transaction[] v2transactions: V2Transaction[] } @@ -188,6 +198,7 @@ export type WalletFundSiacoinPayload = { changeAddress: string } export type WalletFundSiacoinResponse = { + basis: ChainIndex transaction: Transaction toSign: string[] dependsOn: Transaction[] | null @@ -203,6 +214,7 @@ export type WalletFundSiafundPayload = { claimAddress: string } export type WalletFundSiafundResponse = { + basis: ChainIndex transaction: Transaction toSign: string[] dependsOn: Transaction[] | null @@ -226,3 +238,34 @@ export type WalletReleasePayload = { siafundOutputs?: SiafundOutputID[] } export type WalletReleaseResponse = void + +export type WalletConstructV1TransactionParams = { + id: string +} +export type WalletConstructV1TransactionPayload = { + siacoins?: SiacoinOutput[] + siafunds?: SiafundOutput[] + changeAddress: Address +} + +export type WalletConstructV1TransactionResponse = { + basis: ChainIndex + id: TransactionID + transaction: Transaction + estimatedFee: Currency +} + +export type WalletConstructV2TransactionParams = { + id: string +} +export type WalletConstructV2TransactionPayload = { + siacoins?: SiacoinOutput[] + siafunds?: SiafundOutput[] + changeAddress: Address +} +export type WalletConstructV2TransactionResponse = { + basis: ChainIndex + id: TransactionID + transaction: V2Transaction + estimatedFee: Currency +}