signet.js 0.0.7 → 0.0.9-retry
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -1
- package/browser/index.browser.cjs +3 -0
- package/browser/index.browser.cjs.map +1 -0
- package/browser/index.browser.js +3 -0
- package/browser/index.browser.js.map +1 -0
- package/node/index.node.cjs +3 -0
- package/node/index.node.cjs.map +1 -0
- package/node/index.node.js +3 -0
- package/node/index.node.js.map +1 -0
- package/package.json +19 -18
- package/types/index.d.cts +1048 -0
- package/types/index.d.ts +1048 -0
- package/.eslintrc.json +0 -67
- package/.prettierrc +0 -1
- package/babel.config.js +0 -6
- package/docs/dist/.vocs/icons/arrow-diagonal.svg +0 -3
- package/docs/dist/.vocs/icons/chevron-down.svg +0 -13
- package/docs/dist/.vocs/icons/chevron-up.svg +0 -13
- package/docs/dist/.vocs/icons/link.svg +0 -3
- package/docs/dist/.vocs/search-index-7b499e25.json +0 -1
- package/docs/dist/assets/arbitrary-hash-Cd6eo8ZD.js +0 -309
- package/docs/dist/assets/broadcast-tx-CeTEE9yX.js +0 -8
- package/docs/dist/assets/btc-rpc-adapter-C-qSHpFV.js +0 -226
- package/docs/dist/assets/chain-adapter-interface-B9TpOgQv.js +0 -1280
- package/docs/dist/assets/chain-contract-interface-DEku3k45.js +0 -392
- package/docs/dist/assets/constructor-73n7bp3b.js +0 -161
- package/docs/dist/assets/constructor-Bg7nvLe0.js +0 -14
- package/docs/dist/assets/contract-addresses-BYlrAOs3.js +0 -200
- package/docs/dist/assets/derive-address-and-public-key-DExrKiGV.js +0 -14
- package/docs/dist/assets/finalize-message-signing-W435d71R.js +0 -20
- package/docs/dist/assets/finalize-transaction-signing-BIgJ2dnc.js +0 -36
- package/docs/dist/assets/finalize-transaction-signing-C--HJs8D.js +0 -24
- package/docs/dist/assets/finalize-transaction-signing-CjGmN7d9.js +0 -24
- package/docs/dist/assets/finalize-typed-data-signing-CEOp_GWt.js +0 -21
- package/docs/dist/assets/get-balance-DBC-i6KG.js +0 -13
- package/docs/dist/assets/get-current-signature-deposit-BXm9AzYy.js +0 -6
- package/docs/dist/assets/get-current-signature-deposit-nOw4j1MN.js +0 -6
- package/docs/dist/assets/get-derived-public-key-BXvfo2m2.js +0 -14
- package/docs/dist/assets/get-derived-public-key-DQ1pyiFS.js +0 -14
- package/docs/dist/assets/get-latest-key-version-DWlkMCre.js +0 -6
- package/docs/dist/assets/get-public-key-B4PFoVqu.js +0 -6
- package/docs/dist/assets/get-public-key-B9xkYkD_.js +0 -6
- package/docs/dist/assets/index-BFuwoY4w.js +0 -601
- package/docs/dist/assets/index-C62Mf-vy.js +0 -426
- package/docs/dist/assets/index-D8xhaiVb.js +0 -121
- package/docs/dist/assets/index-DTr0DlO0.js +0 -36
- package/docs/dist/assets/index-V9dXf-ik.js +0 -457
- package/docs/dist/assets/prepare-message-for-signing-DESTq-Hg.js +0 -16
- package/docs/dist/assets/prepare-transaction-for-signing-DIKTU0zj.js +0 -33
- package/docs/dist/assets/prepare-transaction-for-signing-DV_wkZ5g.js +0 -21
- package/docs/dist/assets/prepare-transaction-for-signing-LVDP0COu.js +0 -33
- package/docs/dist/assets/prepare-typed-data-for-signing-CWcmJvw0.js +0 -192
- package/docs/dist/assets/sign-CwtS5LnB.js +0 -13
- package/docs/dist/assets/sign-OQxf9yn7.js +0 -15
- package/docs/dist/assets/signet-quick-start-CQK52nVG.js +0 -350
- package/docs/dist/assets/sponsor-foreign-chain-gas-C9iWXM8Q.js +0 -1
- package/docs/dist/assets/style-CKGXuRqx.css +0 -1
- package/docs/dist/examples/arbitrary-hash/index.html +0 -88
- package/docs/dist/examples/sponsor-foreign-chain-gas/index.html +0 -21
- package/docs/dist/index.html +0 -56
- package/docs/dist/initializeTheme.iife.js +0 -1
- package/docs/dist/introduction/signet-quick-start/index.html +0 -109
- package/docs/dist/primitives/chain-adapter-interface/index.html +0 -515
- package/docs/dist/primitives/chain-contract-interface/index.html +0 -306
- package/docs/dist/primitives/contract-addresses/index.html +0 -97
- package/docs/dist/signet-logo.png +0 -0
- package/docs/dist/signetjs/chain-adapters/bitcoin/btc-rpc-adapter/index.html +0 -148
- package/docs/dist/signetjs/chain-adapters/bitcoin/finalize-transaction-signing/index.html +0 -41
- package/docs/dist/signetjs/chain-adapters/bitcoin/index.html +0 -187
- package/docs/dist/signetjs/chain-adapters/bitcoin/prepare-transaction-for-signing/index.html +0 -34
- package/docs/dist/signetjs/chain-adapters/broadcast-tx/index.html +0 -28
- package/docs/dist/signetjs/chain-adapters/cosmos/finalize-transaction-signing/index.html +0 -41
- package/docs/dist/signetjs/chain-adapters/cosmos/index.html +0 -166
- package/docs/dist/signetjs/chain-adapters/cosmos/prepare-transaction-for-signing/index.html +0 -43
- package/docs/dist/signetjs/chain-adapters/derive-address-and-public-key/index.html +0 -31
- package/docs/dist/signetjs/chain-adapters/evm/finalize-message-signing/index.html +0 -38
- package/docs/dist/signetjs/chain-adapters/evm/finalize-transaction-signing/index.html +0 -41
- package/docs/dist/signetjs/chain-adapters/evm/finalize-typed-data-signing/index.html +0 -39
- package/docs/dist/signetjs/chain-adapters/evm/index.html +0 -129
- package/docs/dist/signetjs/chain-adapters/evm/prepare-message-for-signing/index.html +0 -31
- package/docs/dist/signetjs/chain-adapters/evm/prepare-transaction-for-signing/index.html +0 -34
- package/docs/dist/signetjs/chain-adapters/evm/prepare-typed-data-for-signing/index.html +0 -49
- package/docs/dist/signetjs/chain-adapters/get-balance/index.html +0 -30
- package/docs/dist/signetjs/contracts/evm/constructor/index.html +0 -45
- package/docs/dist/signetjs/contracts/evm/get-current-signature-deposit/index.html +0 -26
- package/docs/dist/signetjs/contracts/evm/get-derived-public-key/index.html +0 -31
- package/docs/dist/signetjs/contracts/evm/get-latest-key-version/index.html +0 -26
- package/docs/dist/signetjs/contracts/evm/get-public-key/index.html +0 -26
- package/docs/dist/signetjs/contracts/evm/sign/index.html +0 -32
- package/docs/dist/signetjs/contracts/near/constructor/index.html +0 -34
- package/docs/dist/signetjs/contracts/near/get-current-signature-deposit/index.html +0 -26
- package/docs/dist/signetjs/contracts/near/get-derived-public-key/index.html +0 -31
- package/docs/dist/signetjs/contracts/near/get-public-key/index.html +0 -26
- package/docs/dist/signetjs/contracts/near/sign/index.html +0 -32
- package/docs/pages/examples/arbitrary-hash.mdx +0 -73
- package/docs/pages/examples/sponsor-foreign-chain-gas.mdx +0 -1
- package/docs/pages/index.mdx +0 -36
- package/docs/pages/introduction/signet-quick-start.mdx +0 -88
- package/docs/pages/primitives/chain-adapter-interface.mdx +0 -45
- package/docs/pages/primitives/chain-contract-interface.mdx +0 -52
- package/docs/pages/primitives/contract-addresses.mdx +0 -27
- package/docs/pages/signetjs/chain-adapters/bitcoin/btc-rpc-adapter.mdx +0 -26
- package/docs/pages/signetjs/chain-adapters/bitcoin/finalize-transaction-signing.mdx +0 -47
- package/docs/pages/signetjs/chain-adapters/bitcoin/index.mdx +0 -119
- package/docs/pages/signetjs/chain-adapters/bitcoin/prepare-transaction-for-signing.mdx +0 -30
- package/docs/pages/signetjs/chain-adapters/broadcast-tx.mdx +0 -23
- package/docs/pages/signetjs/chain-adapters/cosmos/finalize-transaction-signing.mdx +0 -53
- package/docs/pages/signetjs/chain-adapters/cosmos/index.mdx +0 -108
- package/docs/pages/signetjs/chain-adapters/cosmos/prepare-transaction-for-signing.mdx +0 -39
- package/docs/pages/signetjs/chain-adapters/derive-address-and-public-key.mdx +0 -28
- package/docs/pages/signetjs/chain-adapters/evm/finalize-message-signing.mdx +0 -33
- package/docs/pages/signetjs/chain-adapters/evm/finalize-transaction-signing.mdx +0 -44
- package/docs/pages/signetjs/chain-adapters/evm/finalize-typed-data-signing.mdx +0 -34
- package/docs/pages/signetjs/chain-adapters/evm/index.mdx +0 -84
- package/docs/pages/signetjs/chain-adapters/evm/prepare-message-for-signing.mdx +0 -26
- package/docs/pages/signetjs/chain-adapters/evm/prepare-transaction-for-signing.mdx +0 -30
- package/docs/pages/signetjs/chain-adapters/evm/prepare-typed-data-for-signing.mdx +0 -44
- package/docs/pages/signetjs/chain-adapters/get-balance.mdx +0 -26
- package/docs/pages/signetjs/contracts/evm/constructor.mdx +0 -38
- package/docs/pages/signetjs/contracts/evm/get-current-signature-deposit.mdx +0 -17
- package/docs/pages/signetjs/contracts/evm/get-derived-public-key.mdx +0 -28
- package/docs/pages/signetjs/contracts/evm/get-latest-key-version.mdx +0 -17
- package/docs/pages/signetjs/contracts/evm/get-public-key.mdx +0 -17
- package/docs/pages/signetjs/contracts/evm/sign.mdx +0 -36
- package/docs/pages/signetjs/contracts/near/constructor.mdx +0 -29
- package/docs/pages/signetjs/contracts/near/get-current-signature-deposit.mdx +0 -17
- package/docs/pages/signetjs/contracts/near/get-derived-public-key.mdx +0 -28
- package/docs/pages/signetjs/contracts/near/get-public-key.mdx +0 -17
- package/docs/pages/signetjs/contracts/near/sign.mdx +0 -32
- package/docs/public/signet-logo.png +0 -0
- package/docs/snippets/code/chains.ts +0 -42
- package/docs/snippets/code/contract.ts +0 -44
- package/docs/snippets/code/evm/contract.ts +0 -24
- package/docs/snippets/code/evm/env.ts +0 -16
- package/docs/snippets/code/near/env.ts +0 -13
- package/hardhat.config.mts +0 -19
- package/src/chain-adapters/Bitcoin/BTCRpcAdapter/BTCRpcAdapter.ts +0 -15
- package/src/chain-adapters/Bitcoin/BTCRpcAdapter/Mempool/Mempool.ts +0 -101
- package/src/chain-adapters/Bitcoin/BTCRpcAdapter/Mempool/index.ts +0 -1
- package/src/chain-adapters/Bitcoin/BTCRpcAdapter/Mempool/types.ts +0 -72
- package/src/chain-adapters/Bitcoin/BTCRpcAdapter/index.ts +0 -6
- package/src/chain-adapters/Bitcoin/Bitcoin.ts +0 -287
- package/src/chain-adapters/Bitcoin/index.ts +0 -13
- package/src/chain-adapters/Bitcoin/types.ts +0 -48
- package/src/chain-adapters/Bitcoin/utils.ts +0 -14
- package/src/chain-adapters/ChainAdapter.ts +0 -92
- package/src/chain-adapters/Cosmos/Cosmos.ts +0 -258
- package/src/chain-adapters/Cosmos/index.ts +0 -8
- package/src/chain-adapters/Cosmos/types.ts +0 -35
- package/src/chain-adapters/Cosmos/utils.ts +0 -45
- package/src/chain-adapters/EVM/EVM.test.ts +0 -238
- package/src/chain-adapters/EVM/EVM.ts +0 -337
- package/src/chain-adapters/EVM/index.ts +0 -11
- package/src/chain-adapters/EVM/types.ts +0 -53
- package/src/chain-adapters/EVM/utils.ts +0 -27
- package/src/chain-adapters/index.ts +0 -5
- package/src/constants.ts +0 -62
- package/src/contracts/ChainSignatureContract.ts +0 -65
- package/src/contracts/evm/ChainSignaturesContract.ts +0 -323
- package/src/contracts/evm/ChainSignaturesContractABI.ts +0 -359
- package/src/contracts/evm/errors.ts +0 -52
- package/src/contracts/evm/index.ts +0 -10
- package/src/contracts/evm/types.ts +0 -39
- package/src/contracts/evm/utils.ts +0 -41
- package/src/contracts/index.ts +0 -4
- package/src/contracts/near/ChainSignatureContract.ts +0 -196
- package/src/contracts/near/account.ts +0 -42
- package/src/contracts/near/constants.ts +0 -4
- package/src/contracts/near/index.ts +0 -10
- package/src/contracts/near/signAndSend/index.ts +0 -1
- package/src/contracts/near/signAndSend/keypair.ts +0 -178
- package/src/contracts/near/transaction.ts +0 -202
- package/src/contracts/near/types.ts +0 -71
- package/src/index.ts +0 -5
- package/src/types.ts +0 -46
- package/src/utils/cryptography.ts +0 -141
- package/src/utils/index.ts +0 -1
- package/src/utils/publicKey.ts +0 -17
- package/tsconfig.eslint.json +0 -8
- package/tsconfig.json +0 -126
- package/tsup.config.ts +0 -58
- package/vitest.config.ts +0 -19
- package/vocs.config.ts +0 -213
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { type EncodeObject } from '@cosmjs/proto-signing'
|
|
2
|
-
import { type TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx'
|
|
3
|
-
|
|
4
|
-
export type CosmosNetworkIds = string
|
|
5
|
-
|
|
6
|
-
export type CosmosUnsignedTransaction = TxRaw
|
|
7
|
-
|
|
8
|
-
export interface CosmosTransactionRequest {
|
|
9
|
-
address: string
|
|
10
|
-
publicKey: string
|
|
11
|
-
messages: EncodeObject[]
|
|
12
|
-
memo?: string
|
|
13
|
-
gas?: number
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface BalanceResponse {
|
|
17
|
-
balances: Array<{
|
|
18
|
-
denom: string
|
|
19
|
-
amount: string
|
|
20
|
-
}>
|
|
21
|
-
pagination: {
|
|
22
|
-
next_key: string | null
|
|
23
|
-
total: string
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface ChainInfo {
|
|
28
|
-
prefix: string
|
|
29
|
-
denom: string
|
|
30
|
-
rpcUrl: string
|
|
31
|
-
restUrl: string
|
|
32
|
-
expectedChainId: string
|
|
33
|
-
gasPrice: number
|
|
34
|
-
decimals: number
|
|
35
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { chains, assets } from 'chain-registry'
|
|
2
|
-
|
|
3
|
-
import { type ChainInfo } from '@chain-adapters/Cosmos/types'
|
|
4
|
-
|
|
5
|
-
export const fetchChainInfo = async (chainId: string): Promise<ChainInfo> => {
|
|
6
|
-
const chainInfo = chains.find((chain) => chain.chain_id === chainId)
|
|
7
|
-
if (!chainInfo) {
|
|
8
|
-
throw new Error(`Chain info not found for chainId: ${chainId}`)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const { bech32_prefix: prefix, chain_id: expectedChainId } = chainInfo
|
|
12
|
-
const denom = chainInfo.staking?.staking_tokens?.[0]?.denom
|
|
13
|
-
const rpcUrl = chainInfo.apis?.rpc?.[0]?.address
|
|
14
|
-
const restUrl = chainInfo.apis?.rest?.[0]?.address
|
|
15
|
-
const gasPrice = chainInfo.fees?.fee_tokens?.[0]?.average_gas_price
|
|
16
|
-
|
|
17
|
-
if (
|
|
18
|
-
!prefix ||
|
|
19
|
-
!denom ||
|
|
20
|
-
!rpcUrl ||
|
|
21
|
-
!restUrl ||
|
|
22
|
-
!expectedChainId ||
|
|
23
|
-
gasPrice === undefined
|
|
24
|
-
) {
|
|
25
|
-
throw new Error(
|
|
26
|
-
`Missing required chain information for ${chainInfo.chain_name}`
|
|
27
|
-
)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const assetList = assets.find(
|
|
31
|
-
(asset) => asset.chain_name === chainInfo.chain_name
|
|
32
|
-
)
|
|
33
|
-
const asset = assetList?.assets.find((asset) => asset.base === denom)
|
|
34
|
-
const decimals = asset?.denom_units.find(
|
|
35
|
-
(unit) => unit.denom === asset.display
|
|
36
|
-
)?.exponent
|
|
37
|
-
|
|
38
|
-
if (decimals === undefined) {
|
|
39
|
-
throw new Error(
|
|
40
|
-
`Could not find decimals for ${denom} on chain ${chainInfo.chain_name}`
|
|
41
|
-
)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return { prefix, denom, rpcUrl, restUrl, expectedChainId, gasPrice, decimals }
|
|
45
|
-
}
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
import { LocalAccountSigner } from '@aa-sdk/core'
|
|
2
|
-
import { alchemy, sepolia as alchemySepolia } from '@account-kit/infra'
|
|
3
|
-
import { createLightAccountAlchemyClient } from '@account-kit/smart-contracts'
|
|
4
|
-
import { secp256k1 } from '@noble/curves/secp256k1'
|
|
5
|
-
import BN from 'bn.js'
|
|
6
|
-
import {
|
|
7
|
-
createPublicClient,
|
|
8
|
-
createWalletClient,
|
|
9
|
-
http,
|
|
10
|
-
parseEther,
|
|
11
|
-
recoverMessageAddress,
|
|
12
|
-
recoverTypedDataAddress,
|
|
13
|
-
} from 'viem'
|
|
14
|
-
import { privateKeyToAccount } from 'viem/accounts'
|
|
15
|
-
import { hardhat } from 'viem/chains'
|
|
16
|
-
import { describe, expect, it } from 'vitest'
|
|
17
|
-
|
|
18
|
-
import type { ChainSignatureContract } from '../../contracts/ChainSignatureContract'
|
|
19
|
-
import type { UncompressedPubKeySEC1 } from '../../types'
|
|
20
|
-
|
|
21
|
-
import { EVM } from './EVM'
|
|
22
|
-
|
|
23
|
-
describe('EVM', async () => {
|
|
24
|
-
const privateKey =
|
|
25
|
-
'0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'
|
|
26
|
-
const testAccount = privateKeyToAccount(privateKey)
|
|
27
|
-
const rpcUrl = 'http://127.0.0.1:8545'
|
|
28
|
-
|
|
29
|
-
const publicClient = createPublicClient({
|
|
30
|
-
chain: hardhat,
|
|
31
|
-
transport: http(rpcUrl),
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
const walletClient = createWalletClient({
|
|
35
|
-
account: testAccount,
|
|
36
|
-
chain: hardhat,
|
|
37
|
-
transport: http(rpcUrl),
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
const contract: ChainSignatureContract = {
|
|
41
|
-
sign: async ({ payload }) => {
|
|
42
|
-
const messageBytes = new Uint8Array(payload)
|
|
43
|
-
const privKeyBytes = new Uint8Array(
|
|
44
|
-
Buffer.from(privateKey.slice(2), 'hex')
|
|
45
|
-
)
|
|
46
|
-
const { r, s, recovery } = secp256k1.sign(messageBytes, privKeyBytes)
|
|
47
|
-
return {
|
|
48
|
-
r: r.toString(16).padStart(64, '0'),
|
|
49
|
-
s: s.toString(16).padStart(64, '0'),
|
|
50
|
-
v: recovery + 27,
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
getDerivedPublicKey: async () => {
|
|
54
|
-
return '04' as UncompressedPubKeySEC1
|
|
55
|
-
},
|
|
56
|
-
getPublicKey: async () => {
|
|
57
|
-
const pubKey = secp256k1.getPublicKey(
|
|
58
|
-
Buffer.from(privateKey.slice(2), 'hex')
|
|
59
|
-
)
|
|
60
|
-
return ('04' +
|
|
61
|
-
Buffer.from(pubKey.slice(1)).toString('hex')) as UncompressedPubKeySEC1
|
|
62
|
-
},
|
|
63
|
-
getCurrentSignatureDeposit: async () => new BN(0),
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const evm = new EVM({
|
|
67
|
-
contract,
|
|
68
|
-
rpcUrl,
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it('should sign a message', async () => {
|
|
72
|
-
const message = 'Hello, World!'
|
|
73
|
-
const { hashToSign } = await evm.prepareMessageForSigning(message)
|
|
74
|
-
|
|
75
|
-
const mpcSignature = await contract.sign({
|
|
76
|
-
payload: hashToSign,
|
|
77
|
-
path: '',
|
|
78
|
-
key_version: 0,
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
const signature = evm.finalizeMessageSigning({
|
|
82
|
-
rsvSignature: mpcSignature,
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
const walletSignature = await walletClient.signMessage({
|
|
86
|
-
message,
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
const recoveredAddress = await recoverMessageAddress({
|
|
90
|
-
message,
|
|
91
|
-
signature: walletSignature,
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
expect(recoveredAddress).toBe(testAccount.address)
|
|
95
|
-
expect(signature).toBe(walletSignature)
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
it('should sign typed data', async () => {
|
|
99
|
-
const typedData = {
|
|
100
|
-
domain: {
|
|
101
|
-
name: 'Test',
|
|
102
|
-
version: '1',
|
|
103
|
-
chainId: hardhat.id,
|
|
104
|
-
verifyingContract:
|
|
105
|
-
'0x1234567890123456789012345678901234567890' as `0x${string}`,
|
|
106
|
-
},
|
|
107
|
-
types: {
|
|
108
|
-
Person: [
|
|
109
|
-
{ name: 'name', type: 'string' },
|
|
110
|
-
{ name: 'wallet', type: 'address' },
|
|
111
|
-
],
|
|
112
|
-
},
|
|
113
|
-
primaryType: 'Person' as const,
|
|
114
|
-
message: {
|
|
115
|
-
name: 'Bob',
|
|
116
|
-
wallet: '0x1234567890123456789012345678901234567890' as `0x${string}`,
|
|
117
|
-
},
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const { hashToSign } = await evm.prepareTypedDataForSigning(typedData)
|
|
121
|
-
|
|
122
|
-
const mpcSignature = await contract.sign({
|
|
123
|
-
payload: hashToSign,
|
|
124
|
-
path: '',
|
|
125
|
-
key_version: 0,
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
const signature = evm.finalizeTypedDataSigning({
|
|
129
|
-
rsvSignature: mpcSignature,
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
const walletSignature = await walletClient.signTypedData(typedData)
|
|
133
|
-
|
|
134
|
-
const recoveredAddress = await recoverTypedDataAddress({
|
|
135
|
-
...typedData,
|
|
136
|
-
signature: walletSignature,
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
expect(recoveredAddress).toBe(testAccount.address)
|
|
140
|
-
expect(signature).toBe(walletSignature)
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
it('should sign a transaction', async () => {
|
|
144
|
-
await publicClient.request({
|
|
145
|
-
// @ts-expect-error: hardhat_setBalance is valid as we are using a hardhat client
|
|
146
|
-
method: 'hardhat_setBalance',
|
|
147
|
-
params: [testAccount.address, '0x4563918244f400000000'], // 5 ETH
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
const transactionInput = {
|
|
151
|
-
from: testAccount.address,
|
|
152
|
-
to: '0x1234567890123456789012345678901234567890' as `0x${string}`,
|
|
153
|
-
value: parseEther('1'),
|
|
154
|
-
maxFeePerGas: parseEther('0.001'),
|
|
155
|
-
maxPriorityFeePerGas: parseEther('0.0001'),
|
|
156
|
-
gas: 21000n,
|
|
157
|
-
nonce: await publicClient.getTransactionCount({
|
|
158
|
-
address: testAccount.address,
|
|
159
|
-
}),
|
|
160
|
-
type: 'eip1559' as const,
|
|
161
|
-
chainId: hardhat.id,
|
|
162
|
-
accessList: [],
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const { hashesToSign, transaction } =
|
|
166
|
-
await evm.prepareTransactionForSigning(transactionInput)
|
|
167
|
-
|
|
168
|
-
const mpcSignature = await contract.sign({
|
|
169
|
-
payload: hashesToSign[0],
|
|
170
|
-
path: '',
|
|
171
|
-
key_version: 0,
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
const tx = evm.finalizeTransactionSigning({
|
|
175
|
-
transaction,
|
|
176
|
-
rsvSignatures: [mpcSignature],
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
const walletSignature = await walletClient.signTransaction(transactionInput)
|
|
180
|
-
|
|
181
|
-
expect(tx).toBe(walletSignature)
|
|
182
|
-
|
|
183
|
-
const txHash = await evm.broadcastTx(tx)
|
|
184
|
-
|
|
185
|
-
const txReceipt = await publicClient.getTransactionReceipt({
|
|
186
|
-
hash: txHash,
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
expect(txReceipt.status).toBe('success')
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
it('should sign a user operation', async () => {
|
|
193
|
-
const lightAccountClient = await createLightAccountAlchemyClient({
|
|
194
|
-
transport: alchemy({ apiKey: 'er9VowLvLw2YQbgTaRLudG81JPxs77rT' }),
|
|
195
|
-
chain: alchemySepolia,
|
|
196
|
-
signer: LocalAccountSigner.privateKeyToAccountSigner(privateKey),
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
const userOp = {
|
|
200
|
-
sender: testAccount.address,
|
|
201
|
-
nonce: '0x0' as `0x${string}`,
|
|
202
|
-
initCode: '0x' as `0x${string}`,
|
|
203
|
-
callData: '0x' as `0x${string}`,
|
|
204
|
-
callGasLimit: '0x5208' as `0x${string}`,
|
|
205
|
-
verificationGasLimit: '0x5208' as `0x${string}`,
|
|
206
|
-
preVerificationGas: '0x5208' as `0x${string}`,
|
|
207
|
-
maxFeePerGas: '0x38d7ea4c68000' as `0x${string}`,
|
|
208
|
-
maxPriorityFeePerGas: '0x5af3107a4000' as `0x${string}`,
|
|
209
|
-
paymasterAndData: '0x' as `0x${string}`,
|
|
210
|
-
signature: '0x' as `0x${string}`,
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
const { hashToSign } = await evm.prepareUserOpForSigning(
|
|
214
|
-
userOp,
|
|
215
|
-
'0x0000000071727De22E5E9d8BAf0edAc6f37da032',
|
|
216
|
-
11155111
|
|
217
|
-
)
|
|
218
|
-
|
|
219
|
-
const mpcSignature = await contract.sign({
|
|
220
|
-
payload: hashToSign,
|
|
221
|
-
path: '',
|
|
222
|
-
key_version: 0,
|
|
223
|
-
})
|
|
224
|
-
|
|
225
|
-
const signedUserOp = evm.finalizeUserOpSigning({
|
|
226
|
-
userOp,
|
|
227
|
-
rsvSignature: mpcSignature,
|
|
228
|
-
})
|
|
229
|
-
|
|
230
|
-
const walletSignature = await lightAccountClient.signUserOperation({
|
|
231
|
-
uoStruct: userOp,
|
|
232
|
-
})
|
|
233
|
-
|
|
234
|
-
expect(signedUserOp.signature).toBe(walletSignature.signature)
|
|
235
|
-
})
|
|
236
|
-
|
|
237
|
-
// TODO: Include test for v7 user operations.
|
|
238
|
-
})
|
|
@@ -1,337 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createPublicClient,
|
|
3
|
-
http,
|
|
4
|
-
parseTransaction,
|
|
5
|
-
type PublicClient,
|
|
6
|
-
hashMessage,
|
|
7
|
-
hashTypedData,
|
|
8
|
-
keccak256,
|
|
9
|
-
toBytes,
|
|
10
|
-
type Hex,
|
|
11
|
-
serializeTransaction,
|
|
12
|
-
type Signature,
|
|
13
|
-
numberToHex,
|
|
14
|
-
getAddress,
|
|
15
|
-
type Address,
|
|
16
|
-
type Hash,
|
|
17
|
-
concatHex,
|
|
18
|
-
encodeAbiParameters,
|
|
19
|
-
hexToBigInt,
|
|
20
|
-
concat,
|
|
21
|
-
pad,
|
|
22
|
-
isAddress,
|
|
23
|
-
} from 'viem'
|
|
24
|
-
|
|
25
|
-
import { ChainAdapter } from '@chain-adapters/ChainAdapter'
|
|
26
|
-
import type {
|
|
27
|
-
EVMTransactionRequest,
|
|
28
|
-
EVMUnsignedTransaction,
|
|
29
|
-
EVMMessage,
|
|
30
|
-
EVMTypedData,
|
|
31
|
-
UserOperationV6,
|
|
32
|
-
UserOperationV7,
|
|
33
|
-
} from '@chain-adapters/EVM/types'
|
|
34
|
-
import { fetchEVMFeeProperties } from '@chain-adapters/EVM/utils'
|
|
35
|
-
import type { BaseChainSignatureContract } from '@contracts/ChainSignatureContract'
|
|
36
|
-
import type { HashToSign, RSVSignature, KeyDerivationPath } from '@types'
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Implementation of the ChainAdapter interface for EVM-compatible networks.
|
|
40
|
-
* Handles interactions with Ethereum Virtual Machine based blockchains like Ethereum, BSC, Polygon, etc.
|
|
41
|
-
*/
|
|
42
|
-
export class EVM extends ChainAdapter<
|
|
43
|
-
EVMTransactionRequest,
|
|
44
|
-
EVMUnsignedTransaction
|
|
45
|
-
> {
|
|
46
|
-
private readonly client: PublicClient
|
|
47
|
-
private readonly contract: BaseChainSignatureContract
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Creates a new EVM chain instance
|
|
51
|
-
* @param params - Configuration parameters
|
|
52
|
-
* @param params.rpcUrl - URL of the EVM JSON-RPC provider (e.g., Infura endpoint)
|
|
53
|
-
* @param params.contract - Instance of the chain signature contract for MPC operations
|
|
54
|
-
*/
|
|
55
|
-
constructor({
|
|
56
|
-
rpcUrl,
|
|
57
|
-
contract,
|
|
58
|
-
}: {
|
|
59
|
-
rpcUrl: string
|
|
60
|
-
contract: BaseChainSignatureContract
|
|
61
|
-
}) {
|
|
62
|
-
super()
|
|
63
|
-
|
|
64
|
-
this.contract = contract
|
|
65
|
-
this.client = createPublicClient({
|
|
66
|
-
transport: http(rpcUrl),
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
private async attachGasAndNonce(
|
|
71
|
-
transaction: EVMTransactionRequest
|
|
72
|
-
): Promise<EVMUnsignedTransaction> {
|
|
73
|
-
const fees = await fetchEVMFeeProperties(this.client, transaction)
|
|
74
|
-
const nonce = await this.client.getTransactionCount({
|
|
75
|
-
address: transaction.from,
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
const { from, ...rest } = transaction
|
|
79
|
-
|
|
80
|
-
return {
|
|
81
|
-
...fees,
|
|
82
|
-
nonce,
|
|
83
|
-
chainId: Number(await this.client.getChainId()),
|
|
84
|
-
type: 'eip1559',
|
|
85
|
-
...rest,
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
private transformRSVSignature(signature: RSVSignature): Signature {
|
|
90
|
-
return {
|
|
91
|
-
r: `0x${signature.r}`,
|
|
92
|
-
s: `0x${signature.s}`,
|
|
93
|
-
yParity: signature.v - 27,
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
private assembleSignature(signature: RSVSignature): Hex {
|
|
98
|
-
const { r, s, yParity } = this.transformRSVSignature(signature)
|
|
99
|
-
|
|
100
|
-
if (yParity === undefined) {
|
|
101
|
-
throw new Error('Missing yParity')
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return concatHex([r, s, numberToHex(yParity + 27, { size: 1 })])
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
async deriveAddressAndPublicKey(
|
|
108
|
-
predecessor: string,
|
|
109
|
-
path: KeyDerivationPath
|
|
110
|
-
): Promise<{
|
|
111
|
-
address: string
|
|
112
|
-
publicKey: string
|
|
113
|
-
}> {
|
|
114
|
-
const uncompressedPubKey = await this.contract.getDerivedPublicKey({
|
|
115
|
-
path,
|
|
116
|
-
predecessor,
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
if (!uncompressedPubKey) {
|
|
120
|
-
throw new Error('Failed to get derived public key')
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const publicKeyNoPrefix = uncompressedPubKey.startsWith('04')
|
|
124
|
-
? uncompressedPubKey.slice(2)
|
|
125
|
-
: uncompressedPubKey
|
|
126
|
-
|
|
127
|
-
const hash = keccak256(Buffer.from(publicKeyNoPrefix, 'hex'))
|
|
128
|
-
const address = getAddress(`0x${hash.slice(-40)}`)
|
|
129
|
-
|
|
130
|
-
return {
|
|
131
|
-
address,
|
|
132
|
-
publicKey: uncompressedPubKey,
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
async getBalance(
|
|
137
|
-
address: string
|
|
138
|
-
): Promise<{ balance: bigint; decimals: number }> {
|
|
139
|
-
const balance = await this.client.getBalance({
|
|
140
|
-
address: address as Address,
|
|
141
|
-
})
|
|
142
|
-
return {
|
|
143
|
-
balance,
|
|
144
|
-
decimals: 18,
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
serializeTransaction(transaction: EVMUnsignedTransaction): `0x${string}` {
|
|
149
|
-
return serializeTransaction(transaction)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
deserializeTransaction(serialized: `0x${string}`): EVMUnsignedTransaction {
|
|
153
|
-
return parseTransaction(serialized) as EVMUnsignedTransaction
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
async prepareTransactionForSigning(
|
|
157
|
-
transactionRequest: EVMTransactionRequest
|
|
158
|
-
): Promise<{
|
|
159
|
-
transaction: EVMUnsignedTransaction
|
|
160
|
-
hashesToSign: HashToSign[]
|
|
161
|
-
}> {
|
|
162
|
-
const transaction = await this.attachGasAndNonce(transactionRequest)
|
|
163
|
-
|
|
164
|
-
const serializedTx = serializeTransaction(transaction)
|
|
165
|
-
const txHash = toBytes(keccak256(serializedTx))
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
transaction,
|
|
169
|
-
hashesToSign: [Array.from(txHash)],
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
async prepareMessageForSigning(message: EVMMessage): Promise<{
|
|
174
|
-
hashToSign: HashToSign
|
|
175
|
-
}> {
|
|
176
|
-
return {
|
|
177
|
-
hashToSign: Array.from(toBytes(hashMessage(message))),
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
async prepareTypedDataForSigning(typedDataRequest: EVMTypedData): Promise<{
|
|
182
|
-
hashToSign: HashToSign
|
|
183
|
-
}> {
|
|
184
|
-
return {
|
|
185
|
-
hashToSign: Array.from(toBytes(hashTypedData(typedDataRequest))),
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* This implementation is a common step for Biconomy and Alchemy.
|
|
191
|
-
* Key differences between implementations:
|
|
192
|
-
* - Signature format: Biconomy omits 0x00 prefix when concatenating, Alchemy includes it
|
|
193
|
-
* - Version support: Biconomy only supports v6, Alchemy supports both v6 and v7
|
|
194
|
-
* - Validation: Biconomy uses modules for signature validation, Alchemy uses built-in validation
|
|
195
|
-
*/
|
|
196
|
-
async prepareUserOpForSigning(
|
|
197
|
-
userOp: UserOperationV7 | UserOperationV6,
|
|
198
|
-
entryPointAddress?: Address,
|
|
199
|
-
chainIdArgs?: number
|
|
200
|
-
): Promise<{
|
|
201
|
-
userOp: UserOperationV7 | UserOperationV6
|
|
202
|
-
hashToSign: HashToSign
|
|
203
|
-
}> {
|
|
204
|
-
const chainId = chainIdArgs ?? (await this.client.getChainId())
|
|
205
|
-
const entryPoint =
|
|
206
|
-
entryPointAddress || '0x0000000071727De22E5E9d8BAf0edAc6f37da032'
|
|
207
|
-
|
|
208
|
-
const encoded = encodeAbiParameters(
|
|
209
|
-
[{ type: 'bytes32' }, { type: 'address' }, { type: 'uint256' }],
|
|
210
|
-
[
|
|
211
|
-
keccak256(
|
|
212
|
-
encodeAbiParameters(
|
|
213
|
-
[
|
|
214
|
-
{ type: 'address' },
|
|
215
|
-
{ type: 'uint256' },
|
|
216
|
-
{ type: 'bytes32' },
|
|
217
|
-
{ type: 'bytes32' },
|
|
218
|
-
{ type: 'bytes32' },
|
|
219
|
-
{ type: 'uint256' },
|
|
220
|
-
{ type: 'bytes32' },
|
|
221
|
-
{ type: 'bytes32' },
|
|
222
|
-
],
|
|
223
|
-
[
|
|
224
|
-
userOp.sender,
|
|
225
|
-
hexToBigInt(userOp.nonce),
|
|
226
|
-
keccak256(
|
|
227
|
-
'factory' in userOp &&
|
|
228
|
-
'factoryData' in userOp &&
|
|
229
|
-
userOp.factory &&
|
|
230
|
-
userOp.factoryData
|
|
231
|
-
? concat([userOp.factory, userOp.factoryData])
|
|
232
|
-
: 'initCode' in userOp
|
|
233
|
-
? userOp.initCode
|
|
234
|
-
: '0x'
|
|
235
|
-
),
|
|
236
|
-
keccak256(userOp.callData),
|
|
237
|
-
concat([
|
|
238
|
-
pad(userOp.verificationGasLimit, { size: 16 }),
|
|
239
|
-
pad(userOp.callGasLimit, { size: 16 }),
|
|
240
|
-
]),
|
|
241
|
-
hexToBigInt(userOp.preVerificationGas),
|
|
242
|
-
concat([
|
|
243
|
-
pad(userOp.maxPriorityFeePerGas, { size: 16 }),
|
|
244
|
-
pad(userOp.maxFeePerGas, { size: 16 }),
|
|
245
|
-
]),
|
|
246
|
-
keccak256(
|
|
247
|
-
'paymaster' in userOp &&
|
|
248
|
-
userOp.paymaster &&
|
|
249
|
-
isAddress(userOp.paymaster)
|
|
250
|
-
? concat([
|
|
251
|
-
userOp.paymaster,
|
|
252
|
-
pad(userOp.paymasterVerificationGasLimit, { size: 16 }),
|
|
253
|
-
pad(userOp.paymasterPostOpGasLimit, { size: 16 }),
|
|
254
|
-
userOp.paymasterData,
|
|
255
|
-
])
|
|
256
|
-
: 'paymasterAndData' in userOp
|
|
257
|
-
? userOp.paymasterAndData
|
|
258
|
-
: '0x'
|
|
259
|
-
),
|
|
260
|
-
]
|
|
261
|
-
)
|
|
262
|
-
),
|
|
263
|
-
entryPoint,
|
|
264
|
-
BigInt(chainId),
|
|
265
|
-
]
|
|
266
|
-
)
|
|
267
|
-
|
|
268
|
-
const userOpHash = keccak256(encoded)
|
|
269
|
-
|
|
270
|
-
return {
|
|
271
|
-
userOp,
|
|
272
|
-
hashToSign: Array.from(toBytes(hashMessage({ raw: userOpHash }))),
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
finalizeTransactionSigning({
|
|
277
|
-
transaction,
|
|
278
|
-
rsvSignatures,
|
|
279
|
-
}: {
|
|
280
|
-
transaction: EVMUnsignedTransaction
|
|
281
|
-
rsvSignatures: RSVSignature[]
|
|
282
|
-
}): `0x02${string}` {
|
|
283
|
-
const signature = this.transformRSVSignature(rsvSignatures[0])
|
|
284
|
-
|
|
285
|
-
return serializeTransaction(transaction, signature)
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
finalizeMessageSigning({
|
|
289
|
-
rsvSignature,
|
|
290
|
-
}: {
|
|
291
|
-
rsvSignature: RSVSignature
|
|
292
|
-
}): Hex {
|
|
293
|
-
return this.assembleSignature(rsvSignature)
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
finalizeTypedDataSigning({
|
|
297
|
-
rsvSignature,
|
|
298
|
-
}: {
|
|
299
|
-
rsvSignature: RSVSignature
|
|
300
|
-
}): Hex {
|
|
301
|
-
return this.assembleSignature(rsvSignature)
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
finalizeUserOpSigning({
|
|
305
|
-
userOp,
|
|
306
|
-
rsvSignature,
|
|
307
|
-
}: {
|
|
308
|
-
userOp: UserOperationV7 | UserOperationV6
|
|
309
|
-
rsvSignature: RSVSignature
|
|
310
|
-
}): UserOperationV7 | UserOperationV6 {
|
|
311
|
-
const { r, s, yParity } = this.transformRSVSignature(rsvSignature)
|
|
312
|
-
if (yParity === undefined) {
|
|
313
|
-
throw new Error('Missing yParity')
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
return {
|
|
317
|
-
...userOp,
|
|
318
|
-
signature: concatHex([
|
|
319
|
-
'0x00', // Alchemy specific implementation. Biconomy doesn't include the 0x00 prefix.
|
|
320
|
-
r,
|
|
321
|
-
s,
|
|
322
|
-
numberToHex(Number(yParity + 27), { size: 1 }),
|
|
323
|
-
]),
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
async broadcastTx(txSerialized: `0x${string}`): Promise<Hash> {
|
|
328
|
-
try {
|
|
329
|
-
return await this.client.sendRawTransaction({
|
|
330
|
-
serializedTransaction: txSerialized,
|
|
331
|
-
})
|
|
332
|
-
} catch (error) {
|
|
333
|
-
console.error('Transaction broadcast failed:', error)
|
|
334
|
-
throw new Error('Failed to broadcast transaction.')
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|