Skip to content
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

WIP: feat(typings): brand Secret, PublicKey, AccounId #214

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@
"js-xdr": "^1.1.1",
"lodash": "^4.17.11",
"sha.js": "^2.3.6",
"tweetnacl": "^1.0.0"
"tweetnacl": "^1.0.0",
"utility-types": "^3.7.0"
},
"optionalDependencies": {
"sodium-native": "^2.3.0"
Expand Down
111 changes: 73 additions & 38 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,46 @@
// TypeScript Version: 2.9

// TypeScript Version: 3.0
/// <reference types="node" />

import { Brand } from "utility-types";

export {};

/**
* 56-character long string, starts with S and passes `StrKey.isValidEd25519SecretSeed()`.
*/
export type Secret = Brand<string, 'Secret'>;

/**
* 56-character long string, starts with G, passes `StrKey.isValidEd25519PublicKey()`
* and account does not exist on the given Network..
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: Extra . --- Network..

*
* See also `AccountId`, `PublicKey`.
*/
export type NonExistingAccountId = Brand<string, 'NonExistingAccountId'>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Akuukis do we need to make this assertion here? I think we can only AccountId regardless if they exist in the network or not.


/**
* 56-character long string, starts with G, passes `StrKey.isValidEd25519PublicKey()`
* and account exists on the given Network.
*
* See also `NonExistingAccountId`, `PublicKey`.
*/
export type AccountId = Brand<string, 'AccountId'>;

/**
* 56-character long string, starts with G and passes `StrKey.isValidEd25519PublicKey()`.
* Does **not** imply that an account with such address exists.
*
* See also `AccountId`, `NonExistingAccountId`.
*/
export type PublicKey = NonExistingAccountId | AccountId;

/**
* `Account` can be created using either `AccountId` or `PublicKey`,
* and it's up to developer to ensure that Account exists at transaction submission.
*/
export class Account {
constructor(accountId: string, sequence: string);
accountId(): string;
constructor(accountId: PublicKey, sequence: string);
accountId(): AccountId;
sequenceNumber(): string;
incrementSequenceNumber(): void;
}
Expand All @@ -24,17 +59,17 @@ export class Asset {
static native(): Asset;
static fromOperation(xdr: xdr.Asset): Asset;

constructor(code: string, issuer: string);
constructor(code: string, issuer: AccountId);

getCode(): string;
getIssuer(): string;
getIssuer(): AccountId;
getAssetType(): AssetType;
isNative(): boolean;
equals(other: Asset): boolean;
toXDRObject(): xdr.Asset;

code: string;
issuer: string;
issuer: AccountId;
}

export const FastSigning: boolean;
Expand All @@ -44,20 +79,20 @@ export type KeypairType = 'ed25519';
export class Keypair {
static fromRawEd25519Seed(secretSeed: Buffer): Keypair;
static fromBase58Seed(secretSeed: string): Keypair;
static fromSecret(secretKey: string): Keypair;
static fromSecret(secretKey: Secret): Keypair;
static master(): Keypair;
static fromPublicKey(publicKey: string): Keypair;
static fromPublicKey(publicKey: PublicKey): Keypair;
static random(): Keypair;

constructor(
keys:
| { type: KeypairType; secretKey: string; publicKey?: string }
| { type: KeypairType; publicKey: string }
| { type: KeypairType; secretKey: Secret; publicKey?: PublicKey }
| { type: KeypairType; publicKey: PublicKey }
);

readonly type: KeypairType;
publicKey(): string;
secret(): string;
publicKey(): PublicKey;
secret(): Secret;
rawPublicKey(): Buffer;
rawSecretKey(): Buffer;
canSign(): boolean;
Expand Down Expand Up @@ -153,7 +188,7 @@ export type AuthFlag =

export namespace Signer {
interface Ed25519PublicKey {
ed25519PublicKey: string;
ed25519PublicKey: PublicKey;
weight: number | undefined;
}
interface Sha256Hash {
Expand All @@ -172,7 +207,7 @@ export type Signer =

export namespace SignerOptions {
interface Ed25519PublicKey {
ed25519PublicKey: string;
ed25519PublicKey: PublicKey;
weight?: number | string;
}
interface Sha256Hash {
Expand Down Expand Up @@ -221,13 +256,13 @@ export type OperationType =

export namespace OperationOptions {
interface BaseOptions {
source?: string;
source?: AccountId;
}
interface AccountMerge extends BaseOptions {
destination: string;
destination: AccountId;
}
interface AllowTrust extends BaseOptions {
trustor: string;
trustor: AccountId;
assetCode: string;
authorize?: boolean;
}
Expand All @@ -236,7 +271,7 @@ export namespace OperationOptions {
limit?: string;
}
interface CreateAccount extends BaseOptions {
destination: string;
destination: NonExistingAccountId;
startingBalance: string;
}
interface CreatePassiveSellOffer extends BaseOptions {
Expand Down Expand Up @@ -266,18 +301,18 @@ export namespace OperationOptions {
interface PathPayment extends BaseOptions {
sendAsset: Asset;
sendMax: string;
destination: string;
destination: AccountId;
destAsset: Asset;
destAmount: string;
path?: Asset[];
}
interface Payment extends BaseOptions {
amount: string;
asset: Asset;
destination: string;
destination: AccountId;
}
interface SetOptions<T extends SignerOptions = never> extends BaseOptions {
inflationDest?: string;
inflationDest?: AccountId;
clearFlags?: AuthFlag;
setFlags?: AuthFlag;
masterWeight?: number | string;
Expand Down Expand Up @@ -309,18 +344,18 @@ export type OperationOptions =
export namespace Operation {
interface BaseOperation<T extends OperationType = OperationType> {
type: T;
source?: string;
source?: AccountId;
}

interface AccountMerge extends BaseOperation<OperationType.AccountMerge> {
destination: string;
destination: NonExistingAccountId;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should probably be AccountId - when you merge the other account exists.

}
function accountMerge(
options: OperationOptions.AccountMerge
): xdr.Operation<AccountMerge>;

interface AllowTrust extends BaseOperation<OperationType.AllowTrust> {
trustor: string;
trustor: AccountId;
assetCode: string;
authorize: boolean | undefined;
}
Expand All @@ -337,7 +372,7 @@ export namespace Operation {
): xdr.Operation<ChangeTrust>;

interface CreateAccount extends BaseOperation<OperationType.CreateAccount> {
destination: string;
destination: AccountId;
startingBalance: string;
}
function createAccount(
Expand Down Expand Up @@ -394,7 +429,7 @@ export namespace Operation {
interface PathPayment extends BaseOperation<OperationType.PathPayment> {
sendAsset: Asset;
sendMax: string;
destination: string;
destination: AccountId;
destAsset: Asset;
destAmount: string;
path: Asset[];
Expand All @@ -406,21 +441,21 @@ export namespace Operation {
interface Payment extends BaseOperation<OperationType.Payment> {
amount: string;
asset: Asset;
destination: string;
destination: AccountId;
}
function payment(options: OperationOptions.Payment): xdr.Operation<Payment>;

interface SetOptions<T extends SignerOptions = SignerOptions>
extends BaseOperation<OperationType.SetOptions> {
inflationDest?: string;
inflationDest?: AccountId;
clearFlags?: AuthFlag;
setFlags?: AuthFlag;
masterWeight?: number;
lowThreshold?: number;
medThreshold?: number;
highThreshold?: number;
homeDomain?: string;
signer: T extends { ed25519PublicKey: any }
signer: T extends { ed25519PublicKey: PublicKey }
? Signer.Ed25519PublicKey
: T extends { sha256Hash: any }
? Signer.Sha256Hash
Expand Down Expand Up @@ -459,13 +494,13 @@ export type Operation =
| Operation.BumpSequence;

export namespace StrKey {
function encodeEd25519PublicKey(data: Buffer): string;
function decodeEd25519PublicKey(data: string): Buffer;
function isValidEd25519PublicKey(Key: string): boolean;
function encodeEd25519PublicKey(data: Buffer): PublicKey;
function decodeEd25519PublicKey(publicKey: PublicKey): Buffer;
function isValidEd25519PublicKey(publicKey: string): publicKey is AccountId;

function encodeEd25519SecretSeed(data: Buffer): string;
function decodeEd25519SecretSeed(data: string): Buffer;
function isValidEd25519SecretSeed(seed: string): boolean;
function encodeEd25519SecretSeed(data: Buffer): Secret;
function decodeEd25519SecretSeed(secret: Secret): Buffer;
function isValidEd25519SecretSeed(secret: string): secret is Secret;

function encodePreAuthTx(data: Buffer): string;
function decodePreAuthTx(data: string): Buffer;
Expand All @@ -479,7 +514,7 @@ export class Transaction<
TOps extends Operation[] = Operation[]
> {
constructor(envelope: string | xdr.TransactionEnvelope);
addSignature(publicKey: string, signature: string): void;
addSignature(publicKey: PublicKey, signature: Secret): void;
getKeypairSignature(keypair: Keypair): string;
hash(): Buffer;
sign(...keypairs: Keypair[]): void;
Expand All @@ -490,7 +525,7 @@ export class Transaction<
operations: TOps;
sequence: string;
fee: number;
source: string;
source: AccountId;
memo: TMemo;
signatures: xdr.DecoratedSignature[];
timeBounds?: {
Expand Down
3 changes: 1 addition & 2 deletions types/test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import * as StellarSdk from 'stellar-base';

const sourceKey = StellarSdk.Keypair.random(); // $ExpectType Keypair
const destKey = StellarSdk.Keypair.random();
const account = new StellarSdk.Account(sourceKey.publicKey(), '1');
const transaction = new StellarSdk.TransactionBuilder(account)
.addOperation(
StellarSdk.Operation.accountMerge({ destination: destKey.publicKey() })
StellarSdk.Operation.accountMerge({ destination: account.accountId() })
)
.addMemo(new StellarSdk.Memo(StellarSdk.MemoText, 'memo'))
.setTimeout(5)
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7603,6 +7603,11 @@ util@^0.10.3:
dependencies:
inherits "2.0.3"

utility-types@^3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.7.0.tgz#51f1c29fa35d4267488345706efcf3f68f2b1933"
integrity sha512-mqRJXN7dEArK/NZNJUubjr9kbFFVZcmF/JHDc9jt5O/aYXUVmopHYujDMhLmLil1Bxo2+khe6KAIVvDH9Yc4VA==

[email protected]:
version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
Expand Down