Skip to content

Commit

Permalink
Address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
h0ngcha0 committed Oct 4, 2024
1 parent 5b89f53 commit 7a6485c
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 40 deletions.
2 changes: 0 additions & 2 deletions packages/web3/src/contract/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,6 @@ export class Contract extends Artifact {
const selectedAccount = await signer.getSelectedAccount()
const signerParams: SignDeployContractChainedTxParams = {
type: 'DeployContract',
publicKey: selectedAccount.publicKey,
signerAddress: selectedAccount.address,
signerKeyType: selectedAccount.keyType,
bytecode: bytecode,
Expand Down Expand Up @@ -760,7 +759,6 @@ export class Script extends Artifact {
const selectedAccount = await signer.getSelectedAccount()
const signerParams: SignExecuteScriptChainedTxParams = {
type: 'ExecuteScript',
publicKey: selectedAccount.publicKey,
signerAddress: selectedAccount.address,
signerKeyType: selectedAccount.keyType,
bytecode: this.buildByteCodeToDeploy(params.initialFields ?? {}),
Expand Down
67 changes: 47 additions & 20 deletions packages/web3/src/signer/tx-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export abstract class TransactionBuilder {
): Promise<Omit<SignTransferTxResult, 'signature'>> {
const data = this.buildTransferTxParams(params, publicKey)
const response = await this.nodeProvider.transactions.postTransactionsBuild(data)
return { ...response, gasPrice: fromApiNumber256(response.gasPrice) }
return this.convertTransferTxResult(response)
}

async buildDeployContractTx(
Expand All @@ -79,8 +79,7 @@ export abstract class TransactionBuilder {
): Promise<Omit<SignDeployContractTxResult, 'signature'>> {
const data = this.buildDeployContractTxParams(params, publicKey)
const response = await this.nodeProvider.contracts.postContractsUnsignedTxDeployContract(data)
const contractId = binToHex(contractIdFromAddress(response.contractAddress))
return { ...response, groupIndex: response.fromGroup, contractId, gasPrice: fromApiNumber256(response.gasPrice) }
return this.convertDeployContractTxResult(response)
}

async buildExecuteScriptTx(
Expand All @@ -89,22 +88,28 @@ export abstract class TransactionBuilder {
): Promise<Omit<SignExecuteScriptTxResult, 'signature'>> {
const data = this.buildExecuteScriptTxParams(params, publicKey)
const response = await this.nodeProvider.contracts.postContractsUnsignedTxExecuteScript(data)
return { ...response, groupIndex: response.fromGroup, gasPrice: fromApiNumber256(response.gasPrice) }
return this.convertExecuteScriptTxResult(response)
}

async buildChainedTx(params: BuildChainedTxParams[]): Promise<BuildChainedTxResult[]> {
const data: BuildTransaction[] = params.map((param) => {
async buildChainedTx(params: BuildChainedTxParams[], publicKeys: string[]): Promise<BuildChainedTxResult[]> {
if (params.length !== publicKeys.length) {
throw new Error(
'The number of build chained transaction parameters must match the number of public keys provided'
)
}

const data: BuildTransaction[] = params.map((param, index) => {
switch (param.type) {
case 'Transfer': {
const value = this.buildTransferTxParams(param, param.publicKey)
const value = this.buildTransferTxParams(param, publicKeys[index])
return { type: param.type, value }
}
case 'DeployContract': {
const value = this.buildDeployContractTxParams(param, param.publicKey)
const value = this.buildDeployContractTxParams(param, publicKeys[index])
return { type: param.type, value }
}
case 'ExecuteScript': {
const value = this.buildExecuteScriptTxParams(param, param.publicKey)
const value = this.buildExecuteScriptTxParams(param, publicKeys[index])
return { type: param.type, value }
}
default:
Expand All @@ -119,28 +124,21 @@ export abstract class TransactionBuilder {
case 'Transfer': {
const buildTransferTxResult = buildResult.value
return {
...buildTransferTxResult,
gasPrice: fromApiNumber256(buildTransferTxResult.gasPrice),
...this.convertTransferTxResult(buildTransferTxResult),
type: buildResult.type
} as SignTransferChainedTxResult
}
}
case 'DeployContract': {
const buildDeployContractTxResult = buildResult.value as BuildDeployContractTxResult
const contractId = binToHex(contractIdFromAddress(buildDeployContractTxResult.contractAddress))
return {
...buildDeployContractTxResult,
groupIndex: buildDeployContractTxResult.fromGroup,
contractId,
gasPrice: fromApiNumber256(buildDeployContractTxResult.gasPrice),
...this.convertDeployContractTxResult(buildDeployContractTxResult),
type: buildResult.type
} as SignDeployContractChainedTxResult
}
case 'ExecuteScript': {
const buildExecuteScriptTxResult = buildResult.value
return {
...buildExecuteScriptTxResult,
groupIndex: buildExecuteScriptTxResult.fromGroup,
gasPrice: fromApiNumber256(buildExecuteScriptTxResult.gasPrice),
...this.convertExecuteScriptTxResult(buildExecuteScriptTxResult),
type: buildResult.type
} as SignExecuteScriptChainedTxResult
}
Expand Down Expand Up @@ -211,4 +209,33 @@ export abstract class TransactionBuilder {
...rest
}
}

private convertTransferTxResult(result: node.BuildTransferTxResult): Omit<SignTransferTxResult, 'signature'> {
return {
...result,
gasPrice: fromApiNumber256(result.gasPrice)
}
}

private convertDeployContractTxResult(
result: node.BuildDeployContractTxResult
): Omit<SignDeployContractTxResult, 'signature'> {
const contractId = binToHex(contractIdFromAddress(result.contractAddress))
return {
...result,
groupIndex: result.fromGroup,
contractId,
gasPrice: fromApiNumber256(result.gasPrice)
}
}

private convertExecuteScriptTxResult(
result: node.BuildExecuteScriptTxResult
): Omit<SignExecuteScriptTxResult, 'signature'> {
return {
...result,
groupIndex: result.fromGroup,
gasPrice: fromApiNumber256(result.gasPrice)
}
}
}
5 changes: 2 additions & 3 deletions packages/web3/src/signer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,11 @@ export interface SignUnsignedTxResult {
}
assertType<Eq<SignUnsignedTxResult, SignTransferTxResult>>

export type SignTransferChainedTxParams = SignTransferTxParams & { type: 'Transfer'; publicKey: string }
export type SignTransferChainedTxParams = SignTransferTxParams & { type: 'Transfer' }
export type SignDeployContractChainedTxParams = SignDeployContractTxParams & {
type: 'DeployContract'
publicKey: string
}
export type SignExecuteScriptChainedTxParams = SignExecuteScriptTxParams & { type: 'ExecuteScript'; publicKey: string }
export type SignExecuteScriptChainedTxParams = SignExecuteScriptTxParams & { type: 'ExecuteScript' }
export type BuildChainedTxParams =
| SignTransferChainedTxParams
| SignDeployContractChainedTxParams
Expand Down
68 changes: 53 additions & 15 deletions test/transaction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,12 @@ describe('transactions', function () {
const transferFrom1To2: SignTransferChainedTxParams = {
signerAddress: signer1.address,
destinations: [{ address: signer2.address, attoAlphAmount: 10n * ONE_ALPH }],
publicKey: signer1.publicKey,
type: 'Transfer'
}

const transferFrom2To3: SignTransferChainedTxParams = {
signerAddress: signer2.address,
destinations: [{ address: signer3.address, attoAlphAmount: 5n * ONE_ALPH }],
publicKey: signer2.publicKey,
type: 'Transfer'
}

Expand All @@ -130,7 +128,8 @@ describe('transactions', function () {
)

const [transferFrom1To2Result, transferFrom2To3Result] = await TransactionBuilder.from(nodeProvider).buildChainedTx(
[transferFrom1To2, transferFrom2To3]
[transferFrom1To2, transferFrom2To3],
[signer1.publicKey, signer2.publicKey]
)

const signedTransferFrom1To2 = await signer1.signAndSubmitUnsignedTx({
Expand Down Expand Up @@ -175,14 +174,13 @@ describe('transactions', function () {
const transferTxParams: SignTransferChainedTxParams = {
signerAddress: signer1.address,
destinations: [{ address: signer2.address, attoAlphAmount: 10n * ONE_ALPH }],
type: 'Transfer',
publicKey: signer1.publicKey
type: 'Transfer'
}

const [transferResult, deployResult] = await TransactionBuilder.from(nodeProvider).buildChainedTx([
transferTxParams,
deployTxParams
])
const [transferResult, deployResult] = await TransactionBuilder.from(nodeProvider).buildChainedTx(
[transferTxParams, deployTxParams],
[signer1.publicKey, signer2.publicKey]
)

await signer1.signAndSubmitUnsignedTx({
unsignedTx: transferResult.unsignedTx,
Expand Down Expand Up @@ -238,14 +236,13 @@ describe('transactions', function () {
const transferTxParams: SignTransferChainedTxParams = {
signerAddress: signer1.address,
destinations: [{ address: signer2.address, attoAlphAmount: 10n * ONE_ALPH }],
type: 'Transfer',
publicKey: signer1.publicKey
type: 'Transfer'
}

const [transferResult, depositResult] = await TransactionBuilder.from(nodeProvider).buildChainedTx([
transferTxParams,
depositTxParams
])
const [transferResult, depositResult] = await TransactionBuilder.from(nodeProvider).buildChainedTx(
[transferTxParams, depositTxParams],
[signer1.publicKey, signer2.publicKey]
)

await signer1.signAndSubmitUnsignedTx({
unsignedTx: transferResult.unsignedTx,
Expand Down Expand Up @@ -274,4 +271,45 @@ describe('transactions', function () {
const contractState = await transactInstance.fetchState()
expect(contractState.fields.totalALPH).toEqual(ONE_ALPH)
})

it.only('should fail when public keys do not match the build chained transactions parameters', 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 transferFrom1To2: SignTransferChainedTxParams = {
signerAddress: signer1.address,
destinations: [{ address: signer2.address, attoAlphAmount: 10n * ONE_ALPH }],
type: 'Transfer'
}

const transferFrom2To3: SignTransferChainedTxParams = {
signerAddress: signer2.address,
destinations: [{ address: signer3.address, attoAlphAmount: 5n * ONE_ALPH }],
type: 'Transfer'
}

await expect(
TransactionBuilder.from(nodeProvider).buildChainedTx([transferFrom1To2, transferFrom2To3], [signer1.publicKey])
).rejects.toThrow(
'The number of build chained transaction parameters must match the number of public keys provided'
)

await expect(
TransactionBuilder.from(nodeProvider).buildChainedTx(
[transferFrom1To2, transferFrom2To3],
[signer1.publicKey, signer2.publicKey, signer1.publicKey]
)
).rejects.toThrow(
'The number of build chained transaction parameters must match the number of public keys provided'
)

await expect(
TransactionBuilder.from(nodeProvider).buildChainedTx(
[transferFrom1To2, transferFrom2To3],
[signer2.publicKey, signer1.publicKey]
)
).rejects.toThrow('Unmatched public key')
})
})

0 comments on commit 7a6485c

Please sign in to comment.