-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add entrypoints #514
Add entrypoints #514
Changes from 9 commits
80698cc
97bf2d1
6a55710
af35e6a
d4fbf59
c5df031
0be9170
8792820
ab8ec97
497efad
07cf5eb
f2b8631
6a0a4ea
de2fb06
0c4004b
1f3b7d6
a019513
3860d59
a973694
29f017f
489f88a
bc0beab
6bc9456
bb29def
f1c9b9c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,13 @@ | ||
import { Address } from "./address"; | ||
import { LibraryConfig } from "./config"; | ||
import { IAccount } from "./controllers/interfaces"; | ||
import { IAccountBalance, IAddress, INonce } from "./interface"; | ||
import { UserSigner, UserWallet } from "./wallet"; | ||
|
||
/** | ||
* An abstraction representing an account (user or Smart Contract) on the Network. | ||
*/ | ||
export class Account { | ||
export class Account implements IAccount { | ||
/** | ||
* The address of the account. | ||
*/ | ||
|
@@ -15,18 +18,30 @@ export class Account { | |
*/ | ||
nonce: INonce = 0; | ||
|
||
/** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very good that we now have these deprecation markers. |
||
* @deprecated This will be remove with the next release as not needed anymore. | ||
*/ | ||
/** | ||
* The balance of the account. | ||
*/ | ||
balance: IAccountBalance = "0"; | ||
|
||
/** | ||
* The signer of the account. | ||
*/ | ||
signer?: UserSigner; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If possible, let's switch to private access modifier (so that we hide the current workaround of having a "frankenstein" Account). |
||
|
||
/** | ||
* Creates an account object from an address | ||
*/ | ||
constructor(address: IAddress) { | ||
constructor(address: IAddress, signer?: UserSigner) { | ||
this.address = address; | ||
this.signer = signer; | ||
} | ||
|
||
/** | ||
* @deprecated This will be remove with the next release as not needed anymore. | ||
*/ | ||
/** | ||
* Updates account properties (such as nonce, balance). | ||
*/ | ||
|
@@ -61,4 +76,37 @@ export class Account { | |
balance: this.balance.toString(), | ||
}; | ||
} | ||
|
||
sign(data: Uint8Array): Promise<Uint8Array> { | ||
if (!this.signer) { | ||
throw new Error("Signer not initialiezed, please provide the signer when account is instantiated"); | ||
} | ||
return this.signer.sign(data); | ||
} | ||
|
||
static fromPem(path: string, hrp: string = LibraryConfig.DefaultAddressHrp): Account { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in the specs, the static methods are prefixed with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
const userSigner = UserSigner.fromPem(path); | ||
return new Account(userSigner.getAddress(hrp), userSigner); | ||
} | ||
|
||
static fromWallet( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Below (and in PY & specs), we use the term keystore. Perhaps this can also be named |
||
keyFileObject: any, | ||
password: string, | ||
addressIndex?: number, | ||
hrp: string = LibraryConfig.DefaultAddressHrp, | ||
): Account { | ||
const userSigner = UserSigner.fromWallet(keyFileObject, password, addressIndex); | ||
return new Account(userSigner.getAddress(hrp), userSigner); | ||
} | ||
|
||
static fromKeystore( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe should we use the |
||
filePath: string, | ||
password: string, | ||
addressIndex?: number, | ||
hrp: string = LibraryConfig.DefaultAddressHrp, | ||
): Account { | ||
const secretKey = UserWallet.loadSecretKey(filePath, password, addressIndex); | ||
const userSigner = new UserSigner(secretKey); | ||
return new Account(userSigner.getAddress(hrp), userSigner); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,8 +3,9 @@ | |
import { LibraryConfig } from "./config"; | ||
import { CURRENT_NUMBER_OF_SHARDS_WITHOUT_META, METACHAIN_ID, WasmVirtualMachine } from "./constants"; | ||
import * as errors from "./errors"; | ||
import { IAddress } from "./interface"; | ||
import { bigIntToBuffer } from "./tokenOperations/codec"; | ||
const createKeccakHash = require("keccak"); | ||
|
||
/** | ||
* The length (in bytes) of a public key (from which a bech32 address can be obtained). | ||
|
@@ -13,15 +14,10 @@ | |
|
||
const SMART_CONTRACT_HEX_PUBKEY_PREFIX = "0".repeat(16); | ||
|
||
interface IAddress { | ||
getPublicKey(): Buffer; | ||
getHrp(): string; | ||
} | ||
|
||
/** | ||
* An Address, as an immutable object. | ||
*/ | ||
export class Address { | ||
export class Address implements IAddress { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'll drop |
||
private readonly publicKey: Buffer; | ||
private readonly hrp: string; | ||
|
||
|
@@ -298,7 +294,7 @@ | |
|
||
computeContractAddress(deployer: IAddress, deploymentNonce: bigint): Address { | ||
const initialPadding = Buffer.alloc(8, 0); | ||
const ownerPubkey = deployer.getPublicKey(); | ||
const ownerPubkey = deployer.pubkey(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IAddress has only pubkey, we discussed that we will drop that one so.. no need to add extra implementation |
||
const shardSelector = ownerPubkey.slice(30); | ||
const ownerNonceBytes = Buffer.alloc(8); | ||
|
||
|
@@ -315,7 +311,7 @@ | |
} | ||
|
||
getShardOfAddress(address: IAddress): number { | ||
return this.getShardOfPubkey(address.getPublicKey(), this.numberOfShardsWithoutMeta); | ||
return this.getShardOfPubkey(address.pubkey(), this.numberOfShardsWithoutMeta); | ||
} | ||
|
||
private getShardOfPubkey(pubkey: Uint8Array, numberOfShards: number): number { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { IAddress } from "../interface"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the methods |
||
import { Transaction } from "../transaction"; | ||
import { TransactionComputer } from "../transactionComputer"; | ||
import { AccountTransactionsFactory, TransactionsFactoryConfig } from "../transactionsFactories"; | ||
import { IAccount } from "./interfaces"; | ||
|
||
export class AccountController { | ||
private factory: AccountTransactionsFactory; | ||
private txComputer: TransactionComputer; | ||
|
||
constructor(chainId: string) { | ||
this.factory = new AccountTransactionsFactory({ config: new TransactionsFactoryConfig({ chainID: chainId }) }); | ||
this.txComputer = new TransactionComputer(); | ||
} | ||
|
||
async createTransactionForSavingKeyValue(sender: IAccount, options: SaveKeyValueInput): Promise<Transaction> { | ||
const transaction = this.factory.createTransactionForSavingKeyValue({ | ||
sender: sender.address, | ||
keyValuePairs: options.keyValuePairs, | ||
}); | ||
|
||
transaction.nonce = options.nonce; | ||
transaction.signature = await sender.sign(this.txComputer.computeBytesForSigning(transaction)); | ||
|
||
return transaction; | ||
} | ||
|
||
async createTransactionForSettingGuardian(sender: IAccount, options: SetGuardianInput): Promise<Transaction> { | ||
const transaction = this.factory.createTransactionForSettingGuardian({ ...options, sender: sender.address }); | ||
|
||
transaction.nonce = options.nonce; | ||
transaction.signature = await sender.sign(this.txComputer.computeBytesForSigning(transaction)); | ||
|
||
return transaction; | ||
} | ||
|
||
async createTransactionForGuardingAccount( | ||
sender: IAccount, | ||
options: GuardianInteractionInput, | ||
): Promise<Transaction> { | ||
const transaction = this.factory.createTransactionForGuardingAccount({ sender: sender.address }); | ||
|
||
transaction.nonce = options.nonce; | ||
transaction.signature = await sender.sign(this.txComputer.computeBytesForSigning(transaction)); | ||
|
||
return transaction; | ||
} | ||
|
||
async createTransactionForUnguardingAccount( | ||
sender: IAccount, | ||
options: GuardianInteractionInput, | ||
): Promise<Transaction> { | ||
const transaction = this.factory.createTransactionForUnguardingAccount({ sender: sender.address }); | ||
|
||
transaction.nonce = options.nonce; | ||
transaction.signature = await sender.sign(this.txComputer.computeBytesForSigning(transaction)); | ||
|
||
return transaction; | ||
} | ||
} | ||
|
||
type SetGuardianInput = { nonce: bigint; guardianAddress: IAddress; serviceID: string }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very nice 🎉 |
||
type SaveKeyValueInput = { nonce: bigint; keyValuePairs: Map<Uint8Array, Uint8Array> }; | ||
type GuardianInteractionInput = { nonce: bigint }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I know, we are using
bigint
for nonce. Would it be a breaking change if we'd do that here?