commit
d6fe25d696
2
packages/cli/.gitignore
vendored
2
packages/cli/.gitignore
vendored
@ -1,5 +1,3 @@
|
||||
build/
|
||||
dist/
|
||||
docs/
|
||||
|
||||
selftest_userprofile_db/
|
||||
|
||||
@ -64,9 +64,8 @@ const sendTokensMsg: types.MsgSend = {
|
||||
},
|
||||
};
|
||||
|
||||
const signBytes = makeSignBytes([sendTokensMsg], defaultFee, defaultNetworkId, memo, account) as SignableBytes;
|
||||
const rawSignature = await wallet.createTransactionSignature(signer, signBytes, PrehashType.Sha256);
|
||||
const signature = encodeSecp256k1Signature(signer.pubkey.data, rawSignature);
|
||||
const signBytes = makeSignBytes([sendTokensMsg], defaultFee, defaultNetworkId, memo, account);
|
||||
const signature = encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes));
|
||||
const signedTx: types.StdTx = {
|
||||
msg: [sendTokensMsg],
|
||||
fee: defaultFee,
|
||||
|
||||
@ -12,10 +12,7 @@ const defaultFee: types.StdFee = {
|
||||
|
||||
const faucetMnemonic =
|
||||
"economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone";
|
||||
const faucetPath = HdPaths.cosmos(0);
|
||||
const faucetAddress = "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6";
|
||||
|
||||
const wallet = Secp256k1HdWallet.fromMnemonic(faucetMnemonic);
|
||||
const signer = await wallet.createIdentity("unused_value" as ChainId, faucetPath);
|
||||
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucetMnemonic);
|
||||
const client = new RestClient(defaultHttpUrl);
|
||||
|
||||
@ -34,16 +34,13 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@cosmwasm/sdk": "^0.0.3",
|
||||
"@iov/bcp": "^2.0.0-alpha.7",
|
||||
"@iov/crypto": "^2.0.0-alpha.7",
|
||||
"@iov/encoding": "^2.0.0-alpha.7",
|
||||
"@iov/keycontrol": "^2.0.0-alpha.7",
|
||||
"@iov/utils": "^2.0.0-alpha.7",
|
||||
"argparse": "^1.0.10",
|
||||
"babylon": "^6.18.0",
|
||||
"colors": "^1.3.3",
|
||||
"diff": "^4",
|
||||
"leveldown": "^5.0.0",
|
||||
"recast": "^0.18.0",
|
||||
"ts-node": "^8",
|
||||
"typescript": "~3.7"
|
||||
|
||||
@ -38,28 +38,16 @@ export function main(originalArgs: readonly string[]): void {
|
||||
}
|
||||
|
||||
const imports = new Map<string, readonly string[]>([
|
||||
["@cosmwasm/sdk", ["encodeSecp256k1Signature", "makeSignBytes", "marshalTx", "types", "RestClient"]],
|
||||
[
|
||||
"@iov/bcp",
|
||||
"@cosmwasm/sdk",
|
||||
[
|
||||
"Address",
|
||||
"Algorithm",
|
||||
"ChainId",
|
||||
"Nonce",
|
||||
"PrehashType",
|
||||
"PubkeyBytes",
|
||||
"SendTransaction",
|
||||
"SignableBytes",
|
||||
"TokenTicker",
|
||||
"TransactionId",
|
||||
// block info
|
||||
"BlockInfoPending",
|
||||
"BlockInfoSucceeded",
|
||||
"BlockInfoFailed",
|
||||
"BlockInfo",
|
||||
"isBlockInfoPending",
|
||||
"isBlockInfoSucceeded",
|
||||
"isBlockInfoFailed",
|
||||
"encodeSecp256k1Signature",
|
||||
"makeSignBytes",
|
||||
"marshalTx",
|
||||
"Pen",
|
||||
"RestClient",
|
||||
"Secp256k1Pen",
|
||||
"types",
|
||||
],
|
||||
],
|
||||
[
|
||||
@ -90,20 +78,6 @@ export function main(originalArgs: readonly string[]): void {
|
||||
"Uint64",
|
||||
],
|
||||
],
|
||||
[
|
||||
"@iov/keycontrol",
|
||||
[
|
||||
"Ed25519HdWallet",
|
||||
"HdPaths",
|
||||
"Keyring",
|
||||
"Secp256k1HdWallet",
|
||||
"UserProfile",
|
||||
"Wallet",
|
||||
"WalletId",
|
||||
"WalletImplementationIdString",
|
||||
"WalletSerializationString",
|
||||
],
|
||||
],
|
||||
["@iov/utils", ["sleep"]],
|
||||
]);
|
||||
|
||||
@ -111,8 +85,6 @@ export function main(originalArgs: readonly string[]): void {
|
||||
console.info(colors.yellow("Available imports:"));
|
||||
console.info(colors.yellow(" * http"));
|
||||
console.info(colors.yellow(" * https"));
|
||||
console.info(colors.yellow(" * leveldown"));
|
||||
console.info(colors.yellow(" * levelup"));
|
||||
console.info(colors.yellow(" * from long"));
|
||||
console.info(colors.yellow(" - Long"));
|
||||
for (const moduleName of imports.keys()) {
|
||||
@ -128,8 +100,6 @@ export function main(originalArgs: readonly string[]): void {
|
||||
console.info(colors.yellow(" - toHex"));
|
||||
|
||||
let init = `
|
||||
import leveldown = require('leveldown');
|
||||
import levelup from "levelup";
|
||||
import * as http from 'http';
|
||||
import * as https from 'https';
|
||||
import Long from "long";
|
||||
@ -151,11 +121,11 @@ export function main(originalArgs: readonly string[]): void {
|
||||
const hexHash = toHex(hash);
|
||||
export class NewDummyClass {};
|
||||
|
||||
const profile = new UserProfile();
|
||||
const wallet = profile.addWallet(Ed25519HdWallet.fromMnemonic("degree tackle suggest window test behind mesh extra cover prepare oak script"));
|
||||
const db = levelup(leveldown('./selftest_userprofile_db'));
|
||||
await profile.storeIn(db, "secret passwd");
|
||||
const profileFromDb = await UserProfile.loadFrom(db, "secret passwd");
|
||||
const pen = await Secp256k1Pen.fromMnemonic(
|
||||
"zebra slush diet army arrest purpose hawk source west glimpse custom record",
|
||||
);
|
||||
const data = Encoding.toAscii("foo bar");
|
||||
const signature = await pen.createSignature(data);
|
||||
|
||||
console.info("Done testing, will exit now.");
|
||||
process.exit(0);
|
||||
|
||||
@ -43,7 +43,5 @@
|
||||
"axios": "^0.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iov/bcp": "^2.0.0-alpha.7",
|
||||
"@iov/keycontrol": "^2.0.0-alpha.7"
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,4 +4,5 @@ export { CosmosBech32Prefix, decodeBech32Pubkey, encodeAddress, isValidAddress }
|
||||
export { unmarshalTx } from "./decoding";
|
||||
export { encodeSecp256k1Signature, makeSignBytes, marshalTx } from "./encoding";
|
||||
export { RestClient, TxsResponse } from "./restclient";
|
||||
export { makeCosmoshubPath, Pen, PrehashType, Secp256k1Pen } from "./pen";
|
||||
export { types };
|
||||
|
||||
46
packages/sdk/src/pen.spec.ts
Normal file
46
packages/sdk/src/pen.spec.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { Secp256k1, Secp256k1Signature, Sha256 } from "@iov/crypto";
|
||||
import { Encoding } from "@iov/encoding";
|
||||
|
||||
import { Secp256k1Pen } from "./pen";
|
||||
|
||||
const { fromHex } = Encoding;
|
||||
|
||||
describe("Sec256k1Pen", () => {
|
||||
it("can be constructed", async () => {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(
|
||||
"zebra slush diet army arrest purpose hawk source west glimpse custom record",
|
||||
);
|
||||
expect(pen).toBeTruthy();
|
||||
});
|
||||
|
||||
describe("pubkey", () => {
|
||||
it("returns compressed pubkey", async () => {
|
||||
// special sign fit simple patrol salute grocery chicken wheat radar tonight ceiling
|
||||
// m/44'/118'/0'/0/0
|
||||
// pubkey: 02baa4ef93f2ce84592a49b1d729c074eab640112522a7a89f7d03ebab21ded7b6
|
||||
const pen = await Secp256k1Pen.fromMnemonic(
|
||||
"special sign fit simple patrol salute grocery chicken wheat radar tonight ceiling",
|
||||
);
|
||||
expect(pen.pubkey).toEqual(
|
||||
fromHex("02baa4ef93f2ce84592a49b1d729c074eab640112522a7a89f7d03ebab21ded7b6"),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("createSignature", () => {
|
||||
it("creates correct signatures", async () => {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(
|
||||
"special sign fit simple patrol salute grocery chicken wheat radar tonight ceiling",
|
||||
);
|
||||
const data = Encoding.toAscii("foo bar");
|
||||
const signature = await pen.createSignature(data);
|
||||
|
||||
const valid = await Secp256k1.verifySignature(
|
||||
new Secp256k1Signature(signature.slice(0, 32), signature.slice(32, 64)),
|
||||
new Sha256(data).digest(),
|
||||
pen.pubkey,
|
||||
);
|
||||
expect(valid).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
86
packages/sdk/src/pen.ts
Normal file
86
packages/sdk/src/pen.ts
Normal file
@ -0,0 +1,86 @@
|
||||
import {
|
||||
Bip39,
|
||||
EnglishMnemonic,
|
||||
Secp256k1,
|
||||
Sha256,
|
||||
Sha512,
|
||||
Slip10,
|
||||
Slip10Curve,
|
||||
Slip10RawIndex,
|
||||
} from "@iov/crypto";
|
||||
|
||||
export type PrehashType = "sha256" | "sha512" | null;
|
||||
|
||||
/**
|
||||
* A pen is the most basic tool you can think of for signing. It works
|
||||
* everywhere and can be used intuitively by everyone. However, it does not
|
||||
* come with a great amount of features. End of semi suitable metaphor.
|
||||
*
|
||||
* This wraps a single keypair and allows for signing.
|
||||
*
|
||||
* Non-goals of this types are: multi account support, persistency, data migrations,
|
||||
* obfuscation of sensitive data.
|
||||
*/
|
||||
export interface Pen {
|
||||
readonly pubkey: Uint8Array;
|
||||
readonly createSignature: (signBytes: Uint8Array, prehashType?: PrehashType) => Promise<Uint8Array>;
|
||||
}
|
||||
|
||||
function prehash(bytes: Uint8Array, type: PrehashType): Uint8Array {
|
||||
switch (type) {
|
||||
case null:
|
||||
return new Uint8Array([...bytes]);
|
||||
case "sha256":
|
||||
return new Sha256(bytes).digest();
|
||||
case "sha512":
|
||||
return new Sha512(bytes).digest();
|
||||
default:
|
||||
throw new Error("Unknown prehash type");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Cosmoshub derivation path in the form `m/44'/118'/0'/0/a`
|
||||
* with 0-based account index `a`.
|
||||
*/
|
||||
export function makeCosmoshubPath(a: number): readonly Slip10RawIndex[] {
|
||||
return [
|
||||
Slip10RawIndex.hardened(44),
|
||||
Slip10RawIndex.hardened(118),
|
||||
Slip10RawIndex.hardened(0),
|
||||
Slip10RawIndex.normal(0),
|
||||
Slip10RawIndex.normal(a),
|
||||
];
|
||||
}
|
||||
|
||||
export class Secp256k1Pen implements Pen {
|
||||
public static async fromMnemonic(
|
||||
mnemonic: string,
|
||||
hdPath: readonly Slip10RawIndex[] = makeCosmoshubPath(0),
|
||||
): Promise<Secp256k1Pen> {
|
||||
const seed = await Bip39.mnemonicToSeed(new EnglishMnemonic(mnemonic));
|
||||
const { privkey } = Slip10.derivePath(Slip10Curve.Secp256k1, seed, hdPath);
|
||||
const uncompressed = (await Secp256k1.makeKeypair(privkey)).pubkey;
|
||||
return new Secp256k1Pen(privkey, Secp256k1.compressPubkey(uncompressed));
|
||||
}
|
||||
|
||||
public readonly pubkey: Uint8Array;
|
||||
private readonly privkey: Uint8Array;
|
||||
|
||||
private constructor(privkey: Uint8Array, pubkey: Uint8Array) {
|
||||
this.privkey = privkey;
|
||||
this.pubkey = pubkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fixed length encoding of the signature parameters r (32 bytes) and s (32 bytes).
|
||||
*/
|
||||
public async createSignature(
|
||||
signBytes: Uint8Array,
|
||||
prehashType: PrehashType = "sha256",
|
||||
): Promise<Uint8Array> {
|
||||
const message = prehash(signBytes, prehashType);
|
||||
const signature = await Secp256k1.createSignature(message, this.privkey);
|
||||
return new Uint8Array([...signature.r(32), ...signature.s(32)]);
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,11 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
import { ChainId, Identity, PrehashType, SignableBytes } from "@iov/bcp";
|
||||
import { Random } from "@iov/crypto";
|
||||
import { Bech32, Encoding } from "@iov/encoding";
|
||||
import { HdPaths, Secp256k1HdWallet } from "@iov/keycontrol";
|
||||
|
||||
import { encodeSecp256k1Signature, makeSignBytes, marshalTx } from "./encoding";
|
||||
import { leb128Encode } from "./leb128.spec";
|
||||
import { Attribute, Log, parseLogs } from "./logs";
|
||||
import { Pen, Secp256k1Pen } from "./pen";
|
||||
import { PostTxsResponse, RestClient } from "./restclient";
|
||||
import contract from "./testdata/contract.json";
|
||||
import cosmoshub from "./testdata/cosmoshub.json";
|
||||
@ -28,7 +27,6 @@ const httpUrl = "http://localhost:1317";
|
||||
const defaultNetworkId = "testing";
|
||||
const faucetMnemonic =
|
||||
"economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone";
|
||||
const faucetPath = HdPaths.cosmos(0);
|
||||
const faucetAddress = "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6";
|
||||
const emptyAddress = "cosmos1ltkhnmdcqemmd2tkhnx7qx66tq7e0wykw2j85k";
|
||||
|
||||
@ -96,11 +94,7 @@ function findAttribute(logs: readonly Log[], eventType: "message" | "transfer",
|
||||
return out;
|
||||
}
|
||||
|
||||
async function uploadContract(
|
||||
client: RestClient,
|
||||
wallet: Secp256k1HdWallet,
|
||||
signer: Identity,
|
||||
): Promise<PostTxsResponse> {
|
||||
async function uploadContract(client: RestClient, pen: Pen): Promise<PostTxsResponse> {
|
||||
const memo = "My first contract on chain";
|
||||
const theMsg: MsgStoreCode = {
|
||||
type: "wasm/store-code",
|
||||
@ -122,17 +116,15 @@ async function uploadContract(
|
||||
};
|
||||
|
||||
const account = (await client.authAccounts(faucetAddress)).result.value;
|
||||
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account) as SignableBytes;
|
||||
const rawSignature = await wallet.createTransactionSignature(signer, signBytes, PrehashType.Sha256);
|
||||
const signature = encodeSecp256k1Signature(signer.pubkey.data, rawSignature);
|
||||
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account);
|
||||
const signature = encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes));
|
||||
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
|
||||
return client.postTx(marshalTx(signedTx));
|
||||
}
|
||||
|
||||
async function instantiateContract(
|
||||
client: RestClient,
|
||||
wallet: Secp256k1HdWallet,
|
||||
signer: Identity,
|
||||
pen: Pen,
|
||||
codeId: number,
|
||||
beneficiaryAddress: string,
|
||||
transferAmount: readonly Coin[],
|
||||
@ -161,17 +153,15 @@ async function instantiateContract(
|
||||
};
|
||||
|
||||
const account = (await client.authAccounts(faucetAddress)).result.value;
|
||||
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account) as SignableBytes;
|
||||
const rawSignature = await wallet.createTransactionSignature(signer, signBytes, PrehashType.Sha256);
|
||||
const signature = encodeSecp256k1Signature(signer.pubkey.data, rawSignature);
|
||||
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account);
|
||||
const signature = encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes));
|
||||
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
|
||||
return client.postTx(marshalTx(signedTx));
|
||||
}
|
||||
|
||||
async function executeContract(
|
||||
client: RestClient,
|
||||
wallet: Secp256k1HdWallet,
|
||||
signer: Identity,
|
||||
pen: Pen,
|
||||
contractAddress: string,
|
||||
): Promise<PostTxsResponse> {
|
||||
const memo = "Time for action";
|
||||
@ -195,9 +185,8 @@ async function executeContract(
|
||||
};
|
||||
|
||||
const account = (await client.authAccounts(faucetAddress)).result.value;
|
||||
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account) as SignableBytes;
|
||||
const rawSignature = await wallet.createTransactionSignature(signer, signBytes, PrehashType.Sha256);
|
||||
const signature = encodeSecp256k1Signature(signer.pubkey.data, rawSignature);
|
||||
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account);
|
||||
const signature = encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes));
|
||||
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
|
||||
return client.postTx(marshalTx(signedTx));
|
||||
}
|
||||
@ -240,8 +229,7 @@ describe("RestClient", () => {
|
||||
describe("post", () => {
|
||||
it("can send tokens", async () => {
|
||||
pendingWithoutCosmos();
|
||||
const wallet = Secp256k1HdWallet.fromMnemonic(faucetMnemonic);
|
||||
const signer = await wallet.createIdentity("abc" as ChainId, faucetPath);
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucetMnemonic);
|
||||
|
||||
const memo = "My first contract on chain";
|
||||
const theMsg: MsgSend = {
|
||||
@ -271,9 +259,8 @@ describe("RestClient", () => {
|
||||
const client = new RestClient(httpUrl);
|
||||
const account = (await client.authAccounts(faucetAddress)).result.value;
|
||||
|
||||
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account) as SignableBytes;
|
||||
const rawSignature = await wallet.createTransactionSignature(signer, signBytes, PrehashType.Sha256);
|
||||
const signature = encodeSecp256k1Signature(signer.pubkey.data, rawSignature);
|
||||
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account);
|
||||
const signature = encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes));
|
||||
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
|
||||
const result = await client.postTx(marshalTx(signedTx));
|
||||
// console.log("Raw log:", result.raw_log);
|
||||
@ -282,8 +269,7 @@ describe("RestClient", () => {
|
||||
|
||||
it("can upload, instantiate and execute wasm", async () => {
|
||||
pendingWithoutCosmos();
|
||||
const wallet = Secp256k1HdWallet.fromMnemonic(faucetMnemonic);
|
||||
const signer = await wallet.createIdentity("abc" as ChainId, faucetPath);
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucetMnemonic);
|
||||
const client = new RestClient(httpUrl);
|
||||
|
||||
const transferAmount: readonly Coin[] = [
|
||||
@ -303,7 +289,7 @@ describe("RestClient", () => {
|
||||
// upload
|
||||
{
|
||||
// console.log("Raw log:", result.raw_log);
|
||||
const result = await uploadContract(client, wallet, signer);
|
||||
const result = await uploadContract(client, pen);
|
||||
expect(result.code).toBeFalsy();
|
||||
const logs = parseSuccess(result.raw_log);
|
||||
const codeIdAttr = findAttribute(logs, "message", "code_id");
|
||||
@ -316,14 +302,7 @@ describe("RestClient", () => {
|
||||
|
||||
// instantiate
|
||||
{
|
||||
const result = await instantiateContract(
|
||||
client,
|
||||
wallet,
|
||||
signer,
|
||||
codeId,
|
||||
beneficiaryAddress,
|
||||
transferAmount,
|
||||
);
|
||||
const result = await instantiateContract(client, pen, codeId, beneficiaryAddress, transferAmount);
|
||||
expect(result.code).toBeFalsy();
|
||||
// console.log("Raw log:", result.raw_log);
|
||||
const logs = parseSuccess(result.raw_log);
|
||||
@ -338,7 +317,7 @@ describe("RestClient", () => {
|
||||
|
||||
// execute
|
||||
{
|
||||
const result = await executeContract(client, wallet, signer, contractAddress);
|
||||
const result = await executeContract(client, pen, contractAddress);
|
||||
expect(result.code).toBeFalsy();
|
||||
// console.log("Raw log:", result.raw_log);
|
||||
const [firstLog] = parseSuccess(result.raw_log);
|
||||
@ -356,8 +335,7 @@ describe("RestClient", () => {
|
||||
describe("query", () => {
|
||||
it("can list upload code", async () => {
|
||||
pendingWithoutCosmos();
|
||||
const wallet = Secp256k1HdWallet.fromMnemonic(faucetMnemonic);
|
||||
const signer = await wallet.createIdentity("abc" as ChainId, faucetPath);
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucetMnemonic);
|
||||
const client = new RestClient(httpUrl);
|
||||
|
||||
// check with contracts were here first to compare
|
||||
@ -366,7 +344,7 @@ describe("RestClient", () => {
|
||||
const numExisting = existingInfos.length;
|
||||
|
||||
// upload data
|
||||
const result = await uploadContract(client, wallet, signer);
|
||||
const result = await uploadContract(client, pen);
|
||||
expect(result.code).toBeFalsy();
|
||||
const logs = parseSuccess(result.raw_log);
|
||||
const codeIdAttr = findAttribute(logs, "message", "code_id");
|
||||
@ -387,8 +365,7 @@ describe("RestClient", () => {
|
||||
|
||||
it("can list contracts and get info", async () => {
|
||||
pendingWithoutCosmos();
|
||||
const wallet = Secp256k1HdWallet.fromMnemonic(faucetMnemonic);
|
||||
const signer = await wallet.createIdentity("abc" as ChainId, faucetPath);
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucetMnemonic);
|
||||
const client = new RestClient(httpUrl);
|
||||
const beneficiaryAddress = makeRandomAddress();
|
||||
const transferAmount: readonly Coin[] = [
|
||||
@ -404,7 +381,7 @@ describe("RestClient", () => {
|
||||
if (existingInfos.length > 0) {
|
||||
codeId = existingInfos[existingInfos.length - 1].id;
|
||||
} else {
|
||||
const uploaded = await uploadContract(client, wallet, signer);
|
||||
const uploaded = await uploadContract(client, pen);
|
||||
expect(uploaded.code).toBeFalsy();
|
||||
const uploadLogs = parseSuccess(uploaded.raw_log);
|
||||
const codeIdAttr = findAttribute(uploadLogs, "message", "code_id");
|
||||
@ -414,14 +391,7 @@ describe("RestClient", () => {
|
||||
// create new instance and compare before and after
|
||||
const existingContracts = await client.listContractAddresses();
|
||||
|
||||
const result = await instantiateContract(
|
||||
client,
|
||||
wallet,
|
||||
signer,
|
||||
codeId,
|
||||
beneficiaryAddress,
|
||||
transferAmount,
|
||||
);
|
||||
const result = await instantiateContract(client, pen, codeId, beneficiaryAddress, transferAmount);
|
||||
expect(result.code).toBeFalsy();
|
||||
const logs = parseSuccess(result.raw_log);
|
||||
const contractAddressAttr = findAttribute(logs, "message", "contract_address");
|
||||
|
||||
1
packages/sdk/types/index.d.ts
vendored
1
packages/sdk/types/index.d.ts
vendored
@ -3,4 +3,5 @@ export { CosmosBech32Prefix, decodeBech32Pubkey, encodeAddress, isValidAddress }
|
||||
export { unmarshalTx } from "./decoding";
|
||||
export { encodeSecp256k1Signature, makeSignBytes, marshalTx } from "./encoding";
|
||||
export { RestClient, TxsResponse } from "./restclient";
|
||||
export { makeCosmoshubPath, Pen, PrehashType, Secp256k1Pen } from "./pen";
|
||||
export { types };
|
||||
|
||||
31
packages/sdk/types/pen.d.ts
vendored
Normal file
31
packages/sdk/types/pen.d.ts
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
import { Slip10RawIndex } from "@iov/crypto";
|
||||
export declare type PrehashType = "sha256" | "sha512" | null;
|
||||
/**
|
||||
* A pen is the most basic tool you can think of for signing. It works
|
||||
* everywhere and can be used intuitively by everyone. However, it does not
|
||||
* come with a great amount of features. End of semi suitable metaphor.
|
||||
*
|
||||
* This wraps a single keypair and allows for signing.
|
||||
*
|
||||
* Non-goals of this types are: multi account support, persistency, data migrations,
|
||||
* obfuscation of sensitive data.
|
||||
*/
|
||||
export interface Pen {
|
||||
readonly pubkey: Uint8Array;
|
||||
readonly createSignature: (signBytes: Uint8Array, prehashType?: PrehashType) => Promise<Uint8Array>;
|
||||
}
|
||||
/**
|
||||
* The Cosmoshub derivation path in the form `m/44'/118'/0'/0/a`
|
||||
* with 0-based account index `a`.
|
||||
*/
|
||||
export declare function makeCosmoshubPath(a: number): readonly Slip10RawIndex[];
|
||||
export declare class Secp256k1Pen implements Pen {
|
||||
static fromMnemonic(mnemonic: string, hdPath?: readonly Slip10RawIndex[]): Promise<Secp256k1Pen>;
|
||||
readonly pubkey: Uint8Array;
|
||||
private readonly privkey;
|
||||
private constructor();
|
||||
/**
|
||||
* Creates a fixed length encoding of the signature parameters r (32 bytes) and s (32 bytes).
|
||||
*/
|
||||
createSignature(signBytes: Uint8Array, prehashType?: PrehashType): Promise<Uint8Array>;
|
||||
}
|
||||
@ -4,6 +4,7 @@
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"array-type": [true, "array"],
|
||||
"await-promise": true,
|
||||
"callable-types": false,
|
||||
"comment-format": [true, "check-space"],
|
||||
"curly": false,
|
||||
|
||||
19
yarn.lock
19
yarn.lock
@ -4898,15 +4898,6 @@ level-supports@~1.0.0:
|
||||
dependencies:
|
||||
xtend "^4.0.2"
|
||||
|
||||
leveldown@^5.0.0:
|
||||
version "5.4.1"
|
||||
resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-5.4.1.tgz#83a8fdd9bb52b1ed69be2ef59822b6cdfcdb51ec"
|
||||
integrity sha512-3lMPc7eU3yj5g+qF1qlALInzIYnkySIosR1AsUKFjL9D8fYbTLuENBAeDRZXIG4qeWOAyqRItOoLu2v2avWiMA==
|
||||
dependencies:
|
||||
abstract-leveldown "~6.2.1"
|
||||
napi-macros "~2.0.0"
|
||||
node-gyp-build "~4.1.0"
|
||||
|
||||
levelup@^4.0.0:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.3.2.tgz#31c5b1b29f146d1d35d692e01a6da4d28fa55ebd"
|
||||
@ -5517,11 +5508,6 @@ nanomatch@^1.2.9:
|
||||
snapdragon "^0.8.1"
|
||||
to-regex "^3.0.1"
|
||||
|
||||
napi-macros@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b"
|
||||
integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==
|
||||
|
||||
natural-compare@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
@ -5556,11 +5542,6 @@ node-fetch@^2.3.0, node-fetch@^2.5.0:
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
|
||||
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
|
||||
|
||||
node-gyp-build@~4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.1.1.tgz#d7270b5d86717068d114cc57fff352f96d745feb"
|
||||
integrity sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==
|
||||
|
||||
node-gyp@^5.0.2:
|
||||
version "5.0.7"
|
||||
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.0.7.tgz#dd4225e735e840cf2870e4037c2ed9c28a31719e"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user