@turnkey/ethers
Advanced tools
Comparing version 0.19.9 to 1.0.0
@@ -6,7 +6,6 @@ 'use strict'; | ||
class TurnkeySigner extends ethers.ethers.Signer { | ||
class TurnkeySigner extends ethers.AbstractSigner { | ||
constructor(config, provider) { | ||
super(); | ||
super(provider); | ||
this._signTypedData = this.signTypedData.bind(this); | ||
ethers.ethers.utils.defineReadOnly(this, "provider", provider); | ||
this.client = config.client; | ||
@@ -33,3 +32,3 @@ this.organizationId = config.organizationId; | ||
} | ||
if (ethers.ethers.utils.isAddress(this.signWith)) { | ||
if (ethers.isAddress(this.signWith)) { | ||
ethereumAddress = this.signWith; | ||
@@ -90,3 +89,11 @@ } | ||
async signTransaction(transaction) { | ||
const unsignedTx = await ethers.ethers.utils.resolveProperties(transaction); | ||
let { from, to, ...txn } = ethers.copyRequest(transaction); | ||
({ to, from } = await ethers.resolveProperties({ | ||
to: transaction.to | ||
? ethers.resolveAddress(transaction.to, this.provider) | ||
: undefined, | ||
from: transaction.from | ||
? ethers.resolveAddress(transaction.from, this.provider) | ||
: undefined, | ||
})); | ||
// Mimic the behavior of ethers' `Wallet`: | ||
@@ -97,12 +104,15 @@ // - You don't need to pass in `tx.from` | ||
// https://github.com/ethers-io/ethers.js/blob/f97b92bbb1bde22fcc44100af78d7f31602863ab/packages/wallet/src.ts/index.ts#L117-L121 | ||
if (unsignedTx.from != null) { | ||
if (from != null) { | ||
const selfAddress = await this.getAddress(); | ||
if (ethers.ethers.utils.getAddress(unsignedTx.from) !== selfAddress) { | ||
throw new Error(`Transaction \`tx.from\` address mismatch. Self address: ${selfAddress}; \`tx.from\` address: ${unsignedTx.from}`); | ||
if (ethers.getAddress(from) !== selfAddress) { | ||
throw new Error(`Transaction \`tx.from\` address mismatch. Self address: ${selfAddress}; \`tx.from\` address: ${from}`); | ||
} | ||
delete unsignedTx.from; | ||
} | ||
const serializedTx = ethers.ethers.utils.serializeTransaction(unsignedTx); | ||
const nonHexPrefixedSerializedTx = serializedTx.replace(/^0x/, ""); | ||
const signedTx = await this._signTransactionWithErrorWrapping(nonHexPrefixedSerializedTx); | ||
delete transaction.from; | ||
const tx = ethers.Transaction.from({ | ||
...txn, | ||
...(to && { to }), | ||
}); | ||
const unsignedTx = tx.unsignedSerialized.substring(2); | ||
const signedTx = await this._signTransactionWithErrorWrapping(unsignedTx); | ||
return `0x${signedTx}`; | ||
@@ -115,3 +125,3 @@ } | ||
async signMessage(message) { | ||
const hashedMessage = ethers.ethers.utils.hashMessage(message); | ||
const hashedMessage = ethers.hashMessage(message); | ||
const signedMessage = await this._signMessageWithErrorWrapping(hashedMessage); | ||
@@ -151,7 +161,7 @@ return `${signedMessage}`; | ||
let result = assertNonNull(activity?.result?.signRawPayloadResult); | ||
let assembled = ethers.ethers.utils.joinSignature({ | ||
let assembled = ethers.Signature.from({ | ||
r: `0x${result.r}`, | ||
s: `0x${result.s}`, | ||
v: parseInt(result.v) + 27, | ||
}); | ||
}).serialized; | ||
// Assemble the hex | ||
@@ -168,4 +178,3 @@ return assertNonNull(assembled); | ||
async signTypedData(domain, types, value) { | ||
// Populate any ENS names | ||
const populated = await ethers.ethers.utils._TypedDataEncoder.resolveNames(domain, types, value, async (name) => { | ||
const populated = await ethers.TypedDataEncoder.resolveNames(domain, types, value, async (name) => { | ||
assertNonNull(this.provider); | ||
@@ -176,3 +185,3 @@ const address = await this.provider?.resolveName(name); | ||
}); | ||
return this._signMessageWithErrorWrapping(ethers.ethers.utils._TypedDataEncoder.hash(populated.domain, types, populated.value)); | ||
return this._signMessageWithErrorWrapping(ethers.TypedDataEncoder.hash(populated.domain, types, populated.value)); | ||
} | ||
@@ -179,0 +188,0 @@ } |
# @turnkey/ethers | ||
## 1.0.0 | ||
### Major Changes | ||
Updates @turnkey/ethers package and examples to use ethers v6. Refer to https://docs.ethers.org/v6/migrating for full migration instructions. | ||
✨Summary of Changes✨ | ||
`getBalance` is no longer a method on the signer. It must be obtained via the provider instance. | ||
Additionally, it requires an address to be passed in: | ||
``` | ||
// before | ||
const balance = await connectedSigner.getBalance(); | ||
// after | ||
// first get the address | ||
const address = await connectedSigner.getAddress() | ||
// then pass it in | ||
const balance = await connectedSigner.provider?.getBalance(address) | ||
``` | ||
`getChainId` is no longer a method on the signer. It must be obtained via the network object on the provider instance: | ||
``` | ||
// before | ||
const chainId = await connectedSigner.getChainId(); | ||
// after | ||
const chainId = (await connectedSigner.provider?.getNetwork())?.chainId; | ||
``` | ||
`getTransactionCount` is no longer a method on the signer. It must be obtained via the provider instance. | ||
Additionally, it requires an address to be passed in: | ||
``` | ||
// before | ||
const transactionCount = await connectedSigner.getTransactionCount(); | ||
// after | ||
// first get the address | ||
const address = await connectedSigner.getAddress() | ||
// then pass it in | ||
const transactionCount = await connectedSigner.provider?.getTransactionCount(address); | ||
``` | ||
`getFeeData` is no longer a method on the signer. It must be obtained via the provider instance: | ||
``` | ||
// before | ||
const feeData = await connectedSigner.getFeeData(); | ||
// after | ||
const feeData = await connectedSigner.provider?.getFeeData(); | ||
``` | ||
BigNumber -> bigint: numerical values such as, chainId, fee data, balance now use new ES6 primitive `bigint` instead of `BigNumber`. | ||
For example, when checking if the balance is `0`, `bigint` must now be used for comparison: | ||
``` | ||
// before | ||
if (balance.isZero()) {...} | ||
// after | ||
if (balance === 0n) {...} | ||
``` | ||
## 0.19.9 | ||
@@ -4,0 +71,0 @@ |
@@ -1,6 +0,5 @@ | ||
import { ethers } from "ethers"; | ||
import { TransactionRequest, ethers } from "ethers"; | ||
import { TurnkeyActivityError, TurnkeyRequestError } from "@turnkey/http"; | ||
import type { TurnkeyClient } from "@turnkey/http"; | ||
import type { TypedDataSigner } from "@ethersproject/abstract-signer"; | ||
import type { Bytes, TypedDataDomain, TypedDataField } from "ethers"; | ||
import { type TypedDataDomain, type TypedDataField, type Provider, AbstractSigner } from "ethers"; | ||
type TConfig = { | ||
@@ -20,13 +19,13 @@ /** | ||
}; | ||
export declare class TurnkeySigner extends ethers.Signer implements TypedDataSigner { | ||
export declare class TurnkeySigner extends AbstractSigner implements ethers.Signer { | ||
private readonly client; | ||
readonly organizationId: string; | ||
readonly signWith: string; | ||
constructor(config: TConfig, provider?: ethers.providers.Provider); | ||
connect(provider: ethers.providers.Provider): TurnkeySigner; | ||
constructor(config: TConfig, provider?: Provider); | ||
connect(provider: Provider): TurnkeySigner; | ||
getAddress(): Promise<string>; | ||
private _signTransactionImpl; | ||
private _signTransactionWithErrorWrapping; | ||
signTransaction(transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>): Promise<string>; | ||
signMessage(message: string | Bytes): Promise<string>; | ||
signTransaction(transaction: TransactionRequest): Promise<string>; | ||
signMessage(message: string | Uint8Array): Promise<string>; | ||
_signMessageWithErrorWrapping(message: string): Promise<string>; | ||
@@ -33,0 +32,0 @@ _signMessageImpl(message: string): Promise<string>; |
@@ -6,7 +6,6 @@ 'use strict'; | ||
class TurnkeySigner extends ethers.ethers.Signer { | ||
class TurnkeySigner extends ethers.AbstractSigner { | ||
constructor(config, provider) { | ||
super(); | ||
super(provider); | ||
this._signTypedData = this.signTypedData.bind(this); | ||
ethers.ethers.utils.defineReadOnly(this, "provider", provider); | ||
this.client = config.client; | ||
@@ -33,3 +32,3 @@ this.organizationId = config.organizationId; | ||
} | ||
if (ethers.ethers.utils.isAddress(this.signWith)) { | ||
if (ethers.isAddress(this.signWith)) { | ||
ethereumAddress = this.signWith; | ||
@@ -90,3 +89,11 @@ } | ||
async signTransaction(transaction) { | ||
const unsignedTx = await ethers.ethers.utils.resolveProperties(transaction); | ||
let { from, to, ...txn } = ethers.copyRequest(transaction); | ||
({ to, from } = await ethers.resolveProperties({ | ||
to: transaction.to | ||
? ethers.resolveAddress(transaction.to, this.provider) | ||
: undefined, | ||
from: transaction.from | ||
? ethers.resolveAddress(transaction.from, this.provider) | ||
: undefined, | ||
})); | ||
// Mimic the behavior of ethers' `Wallet`: | ||
@@ -97,12 +104,15 @@ // - You don't need to pass in `tx.from` | ||
// https://github.com/ethers-io/ethers.js/blob/f97b92bbb1bde22fcc44100af78d7f31602863ab/packages/wallet/src.ts/index.ts#L117-L121 | ||
if (unsignedTx.from != null) { | ||
if (from != null) { | ||
const selfAddress = await this.getAddress(); | ||
if (ethers.ethers.utils.getAddress(unsignedTx.from) !== selfAddress) { | ||
throw new Error(`Transaction \`tx.from\` address mismatch. Self address: ${selfAddress}; \`tx.from\` address: ${unsignedTx.from}`); | ||
if (ethers.getAddress(from) !== selfAddress) { | ||
throw new Error(`Transaction \`tx.from\` address mismatch. Self address: ${selfAddress}; \`tx.from\` address: ${from}`); | ||
} | ||
delete unsignedTx.from; | ||
} | ||
const serializedTx = ethers.ethers.utils.serializeTransaction(unsignedTx); | ||
const nonHexPrefixedSerializedTx = serializedTx.replace(/^0x/, ""); | ||
const signedTx = await this._signTransactionWithErrorWrapping(nonHexPrefixedSerializedTx); | ||
delete transaction.from; | ||
const tx = ethers.Transaction.from({ | ||
...txn, | ||
...(to && { to }), | ||
}); | ||
const unsignedTx = tx.unsignedSerialized.substring(2); | ||
const signedTx = await this._signTransactionWithErrorWrapping(unsignedTx); | ||
return `0x${signedTx}`; | ||
@@ -115,3 +125,3 @@ } | ||
async signMessage(message) { | ||
const hashedMessage = ethers.ethers.utils.hashMessage(message); | ||
const hashedMessage = ethers.hashMessage(message); | ||
const signedMessage = await this._signMessageWithErrorWrapping(hashedMessage); | ||
@@ -151,7 +161,7 @@ return `${signedMessage}`; | ||
let result = assertNonNull(activity?.result?.signRawPayloadResult); | ||
let assembled = ethers.ethers.utils.joinSignature({ | ||
let assembled = ethers.Signature.from({ | ||
r: `0x${result.r}`, | ||
s: `0x${result.s}`, | ||
v: parseInt(result.v) + 27, | ||
}); | ||
}).serialized; | ||
// Assemble the hex | ||
@@ -168,4 +178,3 @@ return assertNonNull(assembled); | ||
async signTypedData(domain, types, value) { | ||
// Populate any ENS names | ||
const populated = await ethers.ethers.utils._TypedDataEncoder.resolveNames(domain, types, value, async (name) => { | ||
const populated = await ethers.TypedDataEncoder.resolveNames(domain, types, value, async (name) => { | ||
assertNonNull(this.provider); | ||
@@ -176,3 +185,3 @@ const address = await this.provider?.resolveName(name); | ||
}); | ||
return this._signMessageWithErrorWrapping(ethers.ethers.utils._TypedDataEncoder.hash(populated.domain, types, populated.value)); | ||
return this._signMessageWithErrorWrapping(ethers.TypedDataEncoder.hash(populated.domain, types, populated.value)); | ||
} | ||
@@ -179,0 +188,0 @@ } |
{ | ||
"name": "@turnkey/ethers", | ||
"version": "0.19.9", | ||
"version": "1.0.0", | ||
"main": "./dist/index.js", | ||
@@ -43,16 +43,17 @@ "module": "./dist/index.mjs", | ||
"peerDependencies": { | ||
"ethers": "^5.0.0" | ||
"ethers": "^6.10.0" | ||
}, | ||
"dependencies": { | ||
"@ethersproject/abstract-signer": "^5.7.0", | ||
"@turnkey/http": "2.7.1", | ||
"@turnkey/api-key-stamper": "0.4.0" | ||
"@turnkey/api-key-stamper": "0.4.0", | ||
"@turnkey/http": "2.7.1" | ||
}, | ||
"devDependencies": { | ||
"@ethersproject/experimental": "^5.7.0", | ||
"@nomicfoundation/hardhat-ethers": "3.0.5", | ||
"@nomicfoundation/hardhat-network-helpers": "^1.0.8", | ||
"@nomiclabs/hardhat-ethers": "^2.2.3", | ||
"@openzeppelin/contracts": "^4.9.0", | ||
"ethers": "^5.0.0", | ||
"hardhat": "^2.12.7" | ||
"@typechain/ethers-v6": "^0.5.1", | ||
"@typechain/hardhat": "^9.1.0", | ||
"ethers": "^6.10.0", | ||
"hardhat": "^2.19.4", | ||
"typechain": "^8.3.2" | ||
}, | ||
@@ -65,2 +66,3 @@ "engines": { | ||
"clean": "rimraf ./dist ./.cache", | ||
"hardhat:clean": "hardhat clean", | ||
"compile:contracts": "hardhat compile", | ||
@@ -67,0 +69,0 @@ "test": "jest", |
@@ -5,3 +5,3 @@ # @turnkey/ethers | ||
[Turnkey](https://turnkey.com) Signer for [`Ethers`](https://docs.ethers.org/v5/api/signer/). | ||
[Turnkey](https://turnkey.com) Signer for [`Ethers`](https://docs.ethers.org/v6/api/providers/#Signer). | ||
@@ -48,3 +48,3 @@ If you need a lower-level, fully typed HTTP client for interacting with Turnkey API, check out [`@turnkey/http`](/packages/http/). | ||
// Connect it with a Provider (https://docs.ethers.org/v5/api/providers/) | ||
// Connect it with a Provider (https://docs.ethers.org/v6/api/providers/) | ||
const connectedSigner = turnkeySigner.connect(provider); | ||
@@ -51,0 +51,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
65749
3
609
0
8
+ Added@adraffy/ens-normalize@1.10.1(transitive)
+ Added@noble/curves@1.2.0(transitive)
+ Added@noble/hashes@1.3.2(transitive)
+ Added@types/node@18.15.13(transitive)
+ Addedaes-js@4.0.0-beta.5(transitive)
+ Addedethers@6.13.2(transitive)
+ Addedtslib@2.4.0(transitive)
+ Addedws@8.17.1(transitive)
- Removed@ethersproject/abi@5.7.0(transitive)
- Removed@ethersproject/abstract-provider@5.7.0(transitive)
- Removed@ethersproject/abstract-signer@5.7.0(transitive)
- Removed@ethersproject/address@5.7.0(transitive)
- Removed@ethersproject/base64@5.7.0(transitive)
- Removed@ethersproject/basex@5.7.0(transitive)
- Removed@ethersproject/bignumber@5.7.0(transitive)
- Removed@ethersproject/bytes@5.7.0(transitive)
- Removed@ethersproject/constants@5.7.0(transitive)
- Removed@ethersproject/contracts@5.7.0(transitive)
- Removed@ethersproject/hash@5.7.0(transitive)
- Removed@ethersproject/hdnode@5.7.0(transitive)
- Removed@ethersproject/json-wallets@5.7.0(transitive)
- Removed@ethersproject/keccak256@5.7.0(transitive)
- Removed@ethersproject/logger@5.7.0(transitive)
- Removed@ethersproject/networks@5.7.1(transitive)
- Removed@ethersproject/pbkdf2@5.7.0(transitive)
- Removed@ethersproject/properties@5.7.0(transitive)
- Removed@ethersproject/providers@5.7.2(transitive)
- Removed@ethersproject/random@5.7.0(transitive)
- Removed@ethersproject/rlp@5.7.0(transitive)
- Removed@ethersproject/sha2@5.7.0(transitive)
- Removed@ethersproject/signing-key@5.7.0(transitive)
- Removed@ethersproject/solidity@5.7.0(transitive)
- Removed@ethersproject/strings@5.7.0(transitive)
- Removed@ethersproject/transactions@5.7.0(transitive)
- Removed@ethersproject/units@5.7.0(transitive)
- Removed@ethersproject/wallet@5.7.0(transitive)
- Removed@ethersproject/web@5.7.1(transitive)
- Removed@ethersproject/wordlists@5.7.0(transitive)
- Removedaes-js@3.0.0(transitive)
- Removedbech32@1.1.4(transitive)
- Removedbn.js@4.12.05.2.1(transitive)
- Removedbrorand@1.1.0(transitive)
- Removedelliptic@6.5.4(transitive)
- Removedethers@5.7.2(transitive)
- Removedhash.js@1.1.7(transitive)
- Removedhmac-drbg@1.0.1(transitive)
- Removedinherits@2.0.4(transitive)
- Removedjs-sha3@0.8.0(transitive)
- Removedminimalistic-assert@1.0.1(transitive)
- Removedminimalistic-crypto-utils@1.0.1(transitive)
- Removedscrypt-js@3.0.1(transitive)
- Removedws@7.4.6(transitive)