diff --git a/packages/web3-test/src/const.ts b/packages/web3-test/src/const.ts
index 715d54908..8130f213e 100644
--- a/packages/web3-test/src/const.ts
+++ b/packages/web3-test/src/const.ts
@@ -17,6 +17,7 @@ along with the library. If not, see .
*/
import { NodeProvider, web3 } from '@alephium/web3'
+import { PrivateKeyWallet } from '@alephium/web3-wallet'
export const testPrivateKeys = [
'a642942e67258589cd2b1822c631506632db5a12aabcf413604e785300d762a5',
@@ -31,6 +32,7 @@ export const testWalletName = 'alephium-web3-test-only-wallet'
export const testAddress = '1DrDyTr9RpRsQnDnXo2YRiPzPW4ooHX5LLoqXrqfMrpQH'
export const testPrivateKey = testPrivateKeys[0]
export const testPassword = 'alph'
+export const testPrivateKeyWallet = new PrivateKeyWallet({ privateKey: testPrivateKey })
export async function tryGetDevnetNodeProvider(): Promise {
const currentNodeProvider = (() => {
diff --git a/packages/web3-test/src/index.ts b/packages/web3-test/src/index.ts
index fd5d11478..22ac04523 100644
--- a/packages/web3-test/src/index.ts
+++ b/packages/web3-test/src/index.ts
@@ -18,7 +18,7 @@ along with the library. If not, see .
import { disableContractDebugMessage } from '@alephium/web3'
-export { testMnemonic, testWalletName, testAddress, testPrivateKey, testPassword } from './const'
+export { testMnemonic, testWalletName, testAddress, testPrivateKey, testPrivateKeyWallet, testPassword } from './const'
export { mintToken } from './token'
export * from './test-wallet'
diff --git a/packages/web3-test/src/test-wallet.ts b/packages/web3-test/src/test-wallet.ts
index 0c3c5d0fe..0e7044823 100644
--- a/packages/web3-test/src/test-wallet.ts
+++ b/packages/web3-test/src/test-wallet.ts
@@ -35,7 +35,7 @@ import {
testAddress,
testMnemonic,
testPassword,
- testPrivateKey,
+ testPrivateKeyWallet,
testWalletName,
tryGetDevnetNodeProvider
} from './const'
@@ -94,11 +94,10 @@ export async function getSigner(alphAmount = ONE_ALPH * 100n, group = 0): Promis
if (availableBalance < alphAmount) {
throw new Error('Not enough balance, please restart the devnet')
}
- const rootWallet = new PrivateKeyWallet({ privateKey: testPrivateKey })
const wallet = PrivateKeyWallet.Random(group)
if (alphAmount > 0n) {
const destinations = [{ address: wallet.address, attoAlphAmount: alphAmount }]
- await rootWallet.signAndSubmitTransferTx({ signerAddress: testAddress, destinations })
+ await testPrivateKeyWallet.signAndSubmitTransferTx({ signerAddress: testAddress, destinations })
}
return wallet
} catch (error) {
diff --git a/packages/web3-wallet/src/privatekey-wallet.ts b/packages/web3-wallet/src/privatekey-wallet.ts
index 88ad3f2cb..df68972e0 100644
--- a/packages/web3-wallet/src/privatekey-wallet.ts
+++ b/packages/web3-wallet/src/privatekey-wallet.ts
@@ -30,8 +30,16 @@ export class PrivateKeyWallet extends SignerProviderSimple {
readonly publicKey: string
readonly address: string
readonly group: number
- readonly nodeProvider: NodeProvider
- readonly explorerProvider: ExplorerProvider | undefined
+ readonly _nodeProvider: NodeProvider | undefined
+ readonly _explorerProvider: ExplorerProvider | undefined
+
+ public get nodeProvider(): NodeProvider {
+ return this._nodeProvider ?? web3.getCurrentNodeProvider()
+ }
+
+ public get explorerProvider(): ExplorerProvider | undefined {
+ return this._explorerProvider ?? web3.getCurrentExplorerProvider()
+ }
protected unsafeGetSelectedAccount(): Promise {
return Promise.resolve(this.account)
@@ -66,8 +74,8 @@ export class PrivateKeyWallet extends SignerProviderSimple {
this.publicKey = publicKeyFromPrivateKey(privateKey, this.keyType)
this.address = addressFromPublicKey(this.publicKey, this.keyType)
this.group = groupOfAddress(this.address)
- this.nodeProvider = nodeProvider ?? web3.getCurrentNodeProvider()
- this.explorerProvider = explorerProvider ?? web3.getCurrentExplorerProvider()
+ this._nodeProvider = nodeProvider
+ this._explorerProvider = explorerProvider
}
static Random(targetGroup?: number, nodeProvider?: NodeProvider, keyType?: KeyType): PrivateKeyWallet {
diff --git a/test/transaction.test.ts b/test/transaction.test.ts
index 65eb03bd6..7083c6f30 100644
--- a/test/transaction.test.ts
+++ b/test/transaction.test.ts
@@ -17,14 +17,13 @@ along with the library. If not, see .
*/
import { SignTransferChainedTxParams, subscribeToTxStatus } from '../packages/web3'
-import { node } from '../packages/web3'
+import { node, ONE_ALPH } from '../packages/web3'
import { SubscribeOptions, sleep } from '../packages/web3'
import { web3 } from '../packages/web3'
import { TxStatus } from '../packages/web3'
-import { PrivateKeyWallet } from '@alephium/web3-wallet'
-import { ONE_ALPH } from '../packages/web3/src'
+import { HDWallet, HDWalletAccount, PrivateKeyWallet, generateMnemonic } from '@alephium/web3-wallet'
import { Add, Sub, AddMain, Transact, Deposit } from '../artifacts/ts'
-import { getSigner, mintToken } from '@alephium/web3-test'
+import { getSigner, mintToken, testPrivateKeyWallet } from '../packages/web3-test'
import { TransactionBuilder } from '../packages/web3'
import { ALPH_TOKEN_ID } from '../packages/web3'
@@ -105,46 +104,49 @@ describe('transactions', function () {
expect((await addInstance.fetchState()).fields.result).toBe(3n)
})
+ async function prepareChainedTxTest(): Promise<[HDWallet, HDWalletAccount, HDWalletAccount, HDWalletAccount]> {
+ const mnemonic = generateMnemonic()
+ const wallet = new HDWallet({ mnemonic })
+ const address1 = wallet.deriveAndAddNewAccount(1)
+ const address2 = wallet.deriveAndAddNewAccount(2)
+ const address3 = wallet.deriveAndAddNewAccount(3)
+
+ await testPrivateKeyWallet.signAndSubmitTransferTx({
+ signerAddress: testPrivateKeyWallet.address,
+ destinations: [{ address: address1.address, attoAlphAmount: 100n * ONE_ALPH }]
+ })
+
+ return [wallet, address1, address2, address3]
+ }
+
it('should build chained transfer txs across groups', async () => {
const nodeProvider = web3.getCurrentNodeProvider()
- const signer1 = await getSigner(100n * ONE_ALPH, 1)
- const signer2 = await getSigner(0n, 2)
- const signer3 = await getSigner(0n, 3)
+ const [wallet, address1, address2, address3] = await prepareChainedTxTest()
const transferFrom1To2: SignTransferChainedTxParams = {
- signerAddress: signer1.address,
- destinations: [{ address: signer2.address, attoAlphAmount: 10n * ONE_ALPH }],
+ signerAddress: address1.address,
+ destinations: [{ address: address2.address, attoAlphAmount: 10n * ONE_ALPH }],
type: 'Transfer'
}
const transferFrom2To3: SignTransferChainedTxParams = {
- signerAddress: signer2.address,
- destinations: [{ address: signer3.address, attoAlphAmount: 5n * ONE_ALPH }],
+ signerAddress: address2.address,
+ destinations: [{ address: address3.address, attoAlphAmount: 5n * ONE_ALPH }],
type: 'Transfer'
}
- await expect(signer2.signAndSubmitTransferTx(transferFrom2To3)).rejects.toThrow(
+ await expect(wallet.signAndSubmitTransferTx(transferFrom2To3)).rejects.toThrow(
`[API Error] - Not enough balance: got 0, expected 5001000000000000000 - Status code: 500`
)
- const [transferFrom1To2Result, transferFrom2To3Result] = await TransactionBuilder.from(nodeProvider).buildChainedTx(
- [transferFrom1To2, transferFrom2To3],
- [signer1.publicKey, signer2.publicKey]
- )
-
- const signedTransferFrom1To2 = await signer1.signAndSubmitUnsignedTx({
- unsignedTx: transferFrom1To2Result.unsignedTx,
- signerAddress: signer1.address
- })
-
- const signedTransferFrom2To3 = await signer2.signAndSubmitUnsignedTx({
- unsignedTx: transferFrom2To3Result.unsignedTx,
- signerAddress: signer2.address
- })
+ const [signedTransferFrom1To2, signedTransferFrom2To3] = await wallet.signAndSubmitChainedTx([
+ transferFrom1To2,
+ transferFrom2To3
+ ])
- const signer1Balance = await nodeProvider.addresses.getAddressesAddressBalance(signer1.address)
- const signer2Balance = await nodeProvider.addresses.getAddressesAddressBalance(signer2.address)
- const signer3Balance = await nodeProvider.addresses.getAddressesAddressBalance(signer3.address)
+ const signer1Balance = await nodeProvider.addresses.getAddressesAddressBalance(address1.address)
+ const signer2Balance = await nodeProvider.addresses.getAddressesAddressBalance(address2.address)
+ const signer3Balance = await nodeProvider.addresses.getAddressesAddressBalance(address3.address)
const gasCostTransferFrom1To2 = BigInt(signedTransferFrom1To2.gasAmount) * BigInt(signedTransferFrom1To2.gasPrice)
const gasCostTransferFrom2To3 = BigInt(signedTransferFrom2To3.gasAmount) * BigInt(signedTransferFrom2To3.gasPrice)
@@ -159,41 +161,32 @@ describe('transactions', function () {
it('should build chain txs that deploy contract in another group', async () => {
const nodeProvider = web3.getCurrentNodeProvider()
- const signer1 = await getSigner(100n * ONE_ALPH, 1)
- const signer2 = await getSigner(0n, 2)
+ const [wallet, address1, address2] = await prepareChainedTxTest()
- const deployTxParams = await Transact.contract.txParamsForDeployment(signer2, {
+ await wallet.setSelectedAccount(address2.address)
+ const deployTxParams = await Transact.contract.txParamsForDeployment(wallet, {
initialAttoAlphAmount: ONE_ALPH,
initialFields: { tokenId: ALPH_TOKEN_ID, totalALPH: 0n, totalTokens: 0n }
})
+ expect(deployTxParams.signerAddress).toBe(address2.address)
- await expect(signer2.signAndSubmitDeployContractTx(deployTxParams)).rejects.toThrow(
+ await expect(wallet.signAndSubmitDeployContractTx(deployTxParams)).rejects.toThrow(
`[API Error] - Insufficient funds for gas`
)
const transferTxParams: SignTransferChainedTxParams = {
- signerAddress: signer1.address,
- destinations: [{ address: signer2.address, attoAlphAmount: 10n * ONE_ALPH }],
+ signerAddress: address1.address,
+ destinations: [{ address: address2.address, attoAlphAmount: 10n * ONE_ALPH }],
type: 'Transfer'
}
- const [transferResult, deployResult] = await TransactionBuilder.from(nodeProvider).buildChainedTx(
- [transferTxParams, { ...deployTxParams, type: 'DeployContract' }],
- [signer1.publicKey, signer2.publicKey]
- )
+ const [transferResult, deployResult] = await wallet.buildChainedTx([
+ transferTxParams,
+ { ...deployTxParams, type: 'DeployContract' }
+ ])
- await signer1.signAndSubmitUnsignedTx({
- unsignedTx: transferResult.unsignedTx,
- signerAddress: signer1.address
- })
-
- await signer2.signAndSubmitUnsignedTx({
- unsignedTx: deployResult.unsignedTx,
- signerAddress: signer2.address
- })
-
- const signer1Balance = await nodeProvider.addresses.getAddressesAddressBalance(signer1.address)
- const signer2Balance = await nodeProvider.addresses.getAddressesAddressBalance(signer2.address)
+ const signer1Balance = await nodeProvider.addresses.getAddressesAddressBalance(address1.address)
+ const signer2Balance = await nodeProvider.addresses.getAddressesAddressBalance(address2.address)
const transferTxGasCost = BigInt(transferResult.gasAmount) * BigInt(transferResult.gasPrice)
const deployTxGasCost = BigInt(deployResult.gasAmount) * BigInt(deployResult.gasPrice)
@@ -211,8 +204,7 @@ describe('transactions', function () {
it('should build chain txs that interact with dApp in another group', async () => {
const nodeProvider = web3.getCurrentNodeProvider()
- const signer1 = await getSigner(100n * ONE_ALPH, 1)
- const signer2 = await getSigner(0n, 2)
+ const [wallet, address1, address2] = await prepareChainedTxTest()
// Deploy contract in group 2
const deployer = await getSigner(100n * ONE_ALPH, 2)
@@ -224,38 +216,30 @@ describe('transactions', function () {
const transactInstance = deploy.contractInstance
expect(transactInstance.groupIndex).toBe(2)
- const depositTxParams = await Deposit.script.txParamsForExecution(signer2, {
+ await wallet.setSelectedAccount(address2.address)
+ const depositTxParams = await Deposit.script.txParamsForExecution(wallet, {
initialFields: { c: transactInstance.contractId },
attoAlphAmount: ONE_ALPH
})
+ expect(depositTxParams.signerAddress).toBe(address2.address)
- await expect(signer2.signAndSubmitExecuteScriptTx(depositTxParams)).rejects.toThrow(
+ await expect(wallet.signAndSubmitExecuteScriptTx(depositTxParams)).rejects.toThrow(
`[API Error] - Insufficient funds for gas`
)
const transferTxParams: SignTransferChainedTxParams = {
- signerAddress: signer1.address,
- destinations: [{ address: signer2.address, attoAlphAmount: 10n * ONE_ALPH }],
+ signerAddress: address1.address,
+ destinations: [{ address: address2.address, attoAlphAmount: 10n * ONE_ALPH }],
type: 'Transfer'
}
- const [transferResult, depositResult] = await TransactionBuilder.from(nodeProvider).buildChainedTx(
- [transferTxParams, { ...depositTxParams, type: 'ExecuteScript' }],
- [signer1.publicKey, signer2.publicKey]
- )
-
- await signer1.signAndSubmitUnsignedTx({
- unsignedTx: transferResult.unsignedTx,
- signerAddress: signer1.address
- })
-
- await signer2.signAndSubmitUnsignedTx({
- unsignedTx: depositResult.unsignedTx,
- signerAddress: signer2.address
- })
+ const [transferResult, depositResult] = await wallet.buildChainedTx([
+ transferTxParams,
+ { ...depositTxParams, type: 'ExecuteScript' }
+ ])
- const signer1Balance = await nodeProvider.addresses.getAddressesAddressBalance(signer1.address)
- const signer2Balance = await nodeProvider.addresses.getAddressesAddressBalance(signer2.address)
+ const signer1Balance = await nodeProvider.addresses.getAddressesAddressBalance(address1.address)
+ const signer2Balance = await nodeProvider.addresses.getAddressesAddressBalance(address2.address)
const contractBalance = await nodeProvider.addresses.getAddressesAddressBalance(transactInstance.address)
const transferTxGasCost = BigInt(transferResult.gasAmount) * BigInt(transferResult.gasPrice)