Skip to content

Commit

Permalink
Support chained tx in SignerProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
polarker committed Oct 7, 2024
1 parent 841346f commit 2e2881c
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 17 deletions.
1 change: 1 addition & 0 deletions packages/walletconnect/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const RELAY_METHODS = [
'alph_signAndSubmitDeployContractTx',
'alph_signAndSubmitExecuteScriptTx',
'alph_signAndSubmitUnsignedTx',
'alph_signAndSubmitChainedTx',
'alph_signUnsignedTx',
'alph_signMessage',
'alph_requestNodeApi',
Expand Down
8 changes: 7 additions & 1 deletion packages/walletconnect/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ import {
ApiRequestArguments,
NetworkId,
networkIds,
EnableOptionsBase
EnableOptionsBase,
SignChainedTxParams,
SignChainedTxResult
} from '@alephium/web3'

import { ALEPHIUM_DEEP_LINK, LOGGER, PROVIDER_NAMESPACE, RELAY_METHODS, RELAY_URL } from './constants'
Expand Down Expand Up @@ -222,6 +224,10 @@ export class WalletConnectProvider extends SignerProvider {
return this.typedRequest('alph_signAndSubmitUnsignedTx', params)
}

public async signAndSubmitChainedTx(params: SignChainedTxParams[]): Promise<SignChainedTxResult[]> {
return this.typedRequest('alph_signAndSubmitChainedTx', params)
}

public async signUnsignedTx(params: SignUnsignedTxParams): Promise<SignUnsignedTxResult> {
return this.typedRequest('alph_signUnsignedTx', params)
}
Expand Down
8 changes: 7 additions & 1 deletion packages/walletconnect/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ import {
ApiRequestArguments,
assertType,
Eq,
NetworkId
NetworkId,
SignChainedTxParams,
SignChainedTxResult
} from '@alephium/web3'
import { SignClientTypes } from '@walletconnect/types'
import { RELAY_METHODS } from './constants'
Expand All @@ -55,6 +57,10 @@ type RelayMethodsTable = {
params: SignUnsignedTxParams
result: SignUnsignedTxResult
}
alph_signAndSubmitChainedTx: {
params: SignChainedTxParams[]
result: SignChainedTxResult[]
}
alph_signUnsignedTx: {
params: SignUnsignedTxParams
result: SignUnsignedTxResult
Expand Down
35 changes: 24 additions & 11 deletions packages/web3/src/signer/signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import {
Destination,
SignDeployContractTxParams,
SignDeployContractTxResult,
SignerAddress,
SignExecuteScriptTxParams,
SignExecuteScriptTxResult,
SignMessageParams,
Expand All @@ -40,11 +39,12 @@ import {
SubmissionResult,
SubmitTransactionParams,
KeyType,
MessageHasher
MessageHasher,
SignChainedTxParams,
SignChainedTxResult
} from './types'
import { TransactionBuilder } from './tx-builder'
import { addressFromPublicKey, groupOfAddress } from '../address'
import { BuildChainedTx, BuildChainedTxResult } from '../api/api-alephium'

export abstract class SignerProvider {
abstract get nodeProvider(): NodeProvider | undefined
Expand All @@ -69,6 +69,7 @@ export abstract class SignerProvider {
abstract signAndSubmitDeployContractTx(params: SignDeployContractTxParams): Promise<SignDeployContractTxResult>
abstract signAndSubmitExecuteScriptTx(params: SignExecuteScriptTxParams): Promise<SignExecuteScriptTxResult>
abstract signAndSubmitUnsignedTx(params: SignUnsignedTxParams): Promise<SignUnsignedTxResult>
abstract signAndSubmitChainedTx(params: SignChainedTxParams[]): Promise<SignChainedTxResult[]>

abstract signUnsignedTx(params: SignUnsignedTxParams): Promise<SignUnsignedTxResult>
// The message will be prefixed with 'Alephium Signed Message: ' before signing
Expand Down Expand Up @@ -118,17 +119,16 @@ export abstract class SignerProviderSimple extends SignerProvider {
await this.submitTransaction(signResult)
return signResult
}
override async signAndSubmitChainedTx(params: SignChainedTxParams[]): Promise<SignChainedTxResult[]> {
const signResults = await this.signChainedTx(params)
for (const r of signResults) {
await this.submitTransaction(r)
}
return signResults
}

protected abstract getPublicKey(address: string): Promise<string>

private async usePublicKey<T extends SignerAddress>(
params: T
): Promise<Omit<T, 'signerAddress'> & { fromPublicKey: string }> {
const { signerAddress, ...restParams } = params
const publicKey = await this.getPublicKey(signerAddress)
return { fromPublicKey: publicKey, ...restParams }
}

async signTransferTx(params: SignTransferTxParams): Promise<SignTransferTxResult> {
const response = await this.buildTransferTx(params)
const signature = await this.signRaw(params.signerAddress, response.txId)
Expand Down Expand Up @@ -170,6 +170,19 @@ export abstract class SignerProviderSimple extends SignerProvider {
)
}

async signChainedTx(params: SignChainedTxParams[]): Promise<SignChainedTxResult[]> {
const response = await this.buildChainedTx(params)
const signatures = await Promise.all(response.map((r, i) => this.signRaw(params[`${i}`].signerAddress, r.txId)))
return response.map((r, i) => ({ ...r, signature: signatures[`${i}`] } as SignChainedTxResult))
}

async buildChainedTx(params: SignChainedTxParams[]): Promise<Omit<SignChainedTxResult, 'signature'>[]> {
return TransactionBuilder.from(this.nodeProvider).buildChainedTx(
params,
await Promise.all(params.map((p) => this.getPublicKey(p.signerAddress)))
)
}

// in general, wallet should show the decoded information to user for confirmation
// please overwrite this function for real wallet
async signUnsignedTx(params: SignUnsignedTxParams): Promise<SignUnsignedTxResult> {
Expand Down
5 changes: 4 additions & 1 deletion packages/web3/src/signer/tx-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@ export abstract class TransactionBuilder {
return this.convertExecuteScriptTxResult(response)
}

async buildChainedTx(params: SignChainedTxParams[], publicKeys: string[]): Promise<SignChainedTxResult[]> {
async buildChainedTx(
params: SignChainedTxParams[],
publicKeys: string[]
): Promise<Omit<SignChainedTxResult, 'signature'>[]> {
if (params.length !== publicKeys.length) {
throw new Error(
'The number of build chained transaction parameters must match the number of public keys provided'
Expand Down
6 changes: 3 additions & 3 deletions packages/web3/src/signer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,11 @@ export type SignChainedTxParams =
| SignDeployContractChainedTxParams
| SignExecuteScriptChainedTxParams

export type SignTransferChainedTxResult = Omit<SignTransferTxResult, 'signature'> & { type: 'Transfer' }
export type SignDeployContractChainedTxResult = Omit<SignDeployContractTxResult, 'signature'> & {
export type SignTransferChainedTxResult = SignTransferTxResult & { type: 'Transfer' }
export type SignDeployContractChainedTxResult = SignDeployContractTxResult & {
type: 'DeployContract'
}
export type SignExecuteScriptChainedTxResult = Omit<SignExecuteScriptTxResult, 'signature'> & { type: 'ExecuteScript' }
export type SignExecuteScriptChainedTxResult = SignExecuteScriptTxResult & { type: 'ExecuteScript' }
export type SignChainedTxResult =
| SignTransferChainedTxResult
| SignDeployContractChainedTxResult
Expand Down

0 comments on commit 2e2881c

Please sign in to comment.