Merge pull request #284 from CosmWasm/265-wallet-interface-secp256k1-pen
Define Wallet interface and implement for Secp256k1Wallet
This commit is contained in:
commit
33a721ab6d
@ -1,5 +1,7 @@
|
||||
const pen = await Secp256k1Pen.fromMnemonic("enlist hip relief stomach skate base shallow young switch frequent cry park");
|
||||
const senderAddress = pen.address("cosmos");
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(
|
||||
"enlist hip relief stomach skate base shallow young switch frequent cry park",
|
||||
);
|
||||
const [{ address: senderAddress }] = await wallet.getAccounts();
|
||||
|
||||
const client = new CosmosClient("http://localhost:1317");
|
||||
|
||||
@ -11,8 +13,8 @@ const msg: MsgDelegate = {
|
||||
// curl http://localhost:1317/staking/validators | jq '.result[0].operator_address'
|
||||
validator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn",
|
||||
amount: coin(300000, "ustake"),
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
const fee = {
|
||||
amount: coins(2000, "ucosm"),
|
||||
gas: "120000", // 120k
|
||||
@ -26,7 +28,7 @@ const { accountNumber, sequence } = await client.getNonce(senderAddress);
|
||||
console.log("Account/sequence:", accountNumber, sequence);
|
||||
|
||||
const signBytes = makeSignBytes([msg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await pen.sign(signBytes);
|
||||
const signature = await wallet.sign(senderAddress, signBytes);
|
||||
const signedTx: StdTx = {
|
||||
msg: [msg],
|
||||
fee: fee,
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
const mnemonic = "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 mnemonic =
|
||||
"economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone";
|
||||
|
||||
for (let i of [0, 1, 2, 3, 4]) {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(mnemonic, makeCosmoshubPath(i));
|
||||
const pubkey = toBase64(pen.pubkey);
|
||||
const address = pubkeyToAddress(encodeSecp256k1Pubkey(pen.pubkey), "cosmos");
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(mnemonic, makeCosmoshubPath(i), "cosmos");
|
||||
const [{ address, pubkey }] = await wallet.getAccounts();
|
||||
console.info(`Address ${i}: ${address}`);
|
||||
console.info(`Pubkey ${i}: ${pubkey}`);
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
const mnemonic = Bip39.encode(Random.getBytes(16)).toString();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(mnemonic);
|
||||
const pubkey = encodeSecp256k1Pubkey(pen.pubkey);
|
||||
const address = pubkeyToAddress(pubkey, "cosmos");
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(mnemonic);
|
||||
const [{ address, pubkey }] = await wallet.getAccounts();
|
||||
|
||||
console.info("mnemonic:", mnemonic);
|
||||
console.info("pubkey:", pubkey);
|
||||
|
||||
@ -4,7 +4,7 @@ interface Options {
|
||||
feeToken: string;
|
||||
gasPrice: number;
|
||||
bech32prefix: string;
|
||||
};
|
||||
}
|
||||
|
||||
const defaultOptions: Options = {
|
||||
httpUrl: "https://lcd.demo-09.cosmwasm.com",
|
||||
@ -12,7 +12,7 @@ const defaultOptions: Options = {
|
||||
feeToken: "ucosm",
|
||||
gasPrice: 0.025,
|
||||
bech32prefix: "cosmos",
|
||||
}
|
||||
};
|
||||
|
||||
const defaultFaucetUrl = "https://faucet.demo-09.cosmwasm.com/credit";
|
||||
|
||||
@ -22,7 +22,7 @@ const buildFeeTable = (feeToken: string, gasPrice: number): FeeTable => {
|
||||
return {
|
||||
amount: [{ amount: amount.toString(), denom: denom }],
|
||||
gas: gas.toString(),
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
@ -32,7 +32,7 @@ const buildFeeTable = (feeToken: string, gasPrice: number): FeeTable => {
|
||||
exec: stdFee(200000, feeToken, gasPrice),
|
||||
send: stdFee(80000, feeToken, gasPrice),
|
||||
changeAdmin: stdFee(80000, feeToken, gasPrice),
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// TODO: hit faucet
|
||||
@ -43,22 +43,20 @@ const buildFeeTable = (feeToken: string, gasPrice: number): FeeTable => {
|
||||
// }
|
||||
// }
|
||||
|
||||
const penAddress = (pen: Secp256k1Pen, prefix: string): string => {
|
||||
const pubkey = encodeSecp256k1Pubkey(pen.pubkey);
|
||||
return pubkeyToAddress(pubkey, prefix);
|
||||
}
|
||||
|
||||
const connect = async (mnemonic: string, opts: Partial<Options>): Promise<{
|
||||
client: SigningCosmWasmClient,
|
||||
address: string,
|
||||
const connect = async (
|
||||
mnemonic: string,
|
||||
opts: Partial<Options>,
|
||||
): Promise<{
|
||||
client: SigningCosmWasmClient;
|
||||
address: string;
|
||||
}> => {
|
||||
const options: Options = {...defaultOptions, ...opts};
|
||||
const options: Options = { ...defaultOptions, ...opts };
|
||||
const feeTable = buildFeeTable(options.feeToken, options.gasPrice);
|
||||
const pen = await Secp256k1Pen.fromMnemonic(mnemonic);
|
||||
const address = penAddress(pen, options.bech32prefix);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(mnemonic);
|
||||
const [{ address }] = await wallet.getAccounts();
|
||||
|
||||
const client = new SigningCosmWasmClient(options.httpUrl, address, signBytes => pen.sign(signBytes), feeTable);
|
||||
return {client, address};
|
||||
const client = new SigningCosmWasmClient(options.httpUrl, address, wallet, feeTable);
|
||||
return { client, address };
|
||||
};
|
||||
|
||||
// smartQuery assumes the content is proper JSON data and parses before returning it
|
||||
@ -80,32 +78,32 @@ const loadOrCreateMnemonic = (filename: string): string => {
|
||||
fs.writeFileSync(filename, mnemonic, "utf8");
|
||||
return mnemonic;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const hitFaucet = async (faucetUrl: string, address: string, ticker: string): Promise<void> => {
|
||||
const r = await axios.post(defaultFaucetUrl, { ticker, address });
|
||||
console.log(r.status);
|
||||
console.log(r.data);
|
||||
}
|
||||
};
|
||||
|
||||
const randomAddress = async (prefix: string): Promise<string> => {
|
||||
const mnemonic = Bip39.encode(Random.getBytes(16)).toString();
|
||||
return mnemonicToAddress(prefix, mnemonic);
|
||||
}
|
||||
};
|
||||
|
||||
const mnemonicToAddress = async (prefix: string, mnemonic: string): Promise<string> => {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(mnemonic);
|
||||
const pubkey = encodeSecp256k1Pubkey(pen.pubkey);
|
||||
return pubkeyToAddress(pubkey, prefix);
|
||||
}
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(mnemonic);
|
||||
const [{ address }] = await wallet.getAccounts();
|
||||
return address;
|
||||
};
|
||||
|
||||
const downloadWasm = async (url: string): Promise<Uint8Array> => {
|
||||
const r = await axios.get(url, { responseType: "arraybuffer"});
|
||||
const r = await axios.get(url, { responseType: "arraybuffer" });
|
||||
if (r.status !== 200) {
|
||||
throw new Error(`Download error: ${r.status}`);
|
||||
}
|
||||
return r.data;
|
||||
}
|
||||
};
|
||||
|
||||
const getAttibute = (logs: readonly logs.Log[], key: string): string|undefined =>
|
||||
logs[0].events[0].attributes.find(x => x.key == key)?.value
|
||||
const getAttibute = (logs: readonly logs.Log[], key: string): string | undefined =>
|
||||
logs[0].events[0].attributes.find((x) => x.key == key)?.value;
|
||||
|
||||
@ -14,5 +14,5 @@ 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 faucetAddress = "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6";
|
||||
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucetMnemonic);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(faucetMnemonic);
|
||||
const client = new LcdClient(defaultHttpUrl);
|
||||
|
||||
@ -97,10 +97,10 @@ export function main(originalArgs: readonly string[]): void {
|
||||
"MsgDelegate",
|
||||
"MsgSend",
|
||||
"LcdClient",
|
||||
"Pen",
|
||||
"OfflineSigner",
|
||||
"PubKey",
|
||||
"pubkeyToAddress",
|
||||
"Secp256k1Pen",
|
||||
"Secp256k1Wallet",
|
||||
"SigningCosmosClient",
|
||||
"StdFee",
|
||||
"StdTx",
|
||||
@ -145,11 +145,10 @@ export function main(originalArgs: readonly string[]): void {
|
||||
assert(Decimal.fromAtomics("12870000", 6).toString() === "12.87");
|
||||
|
||||
const mnemonic = Bip39.encode(Random.getBytes(16)).toString();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(mnemonic, makeCosmoshubPath(0));
|
||||
const pubkey = encodeSecp256k1Pubkey(pen.pubkey);
|
||||
const address = pubkeyToAddress(pubkey, "cosmos");
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(mnemonic, makeCosmoshubPath(0));
|
||||
const [{ address }] = await wallet.getAccounts();
|
||||
const data = toAscii("foo bar");
|
||||
const signature = await pen.sign(data);
|
||||
const signature = await wallet.sign(address, data);
|
||||
|
||||
console.info("Done testing, will exit now.");
|
||||
process.exit(0);
|
||||
|
||||
@ -7,7 +7,7 @@ import {
|
||||
LcdClient,
|
||||
makeSignBytes,
|
||||
MsgSend,
|
||||
Secp256k1Pen,
|
||||
Secp256k1Wallet,
|
||||
} from "@cosmjs/sdk38";
|
||||
import { assert, sleep } from "@cosmjs/utils";
|
||||
|
||||
@ -48,10 +48,8 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
|
||||
beforeAll(async () => {
|
||||
if (wasmdEnabled()) {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(wasmd.endpoint, alice.address0, (signBytes) =>
|
||||
pen.sign(signBytes),
|
||||
);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(wasmd.endpoint, alice.address0, wallet);
|
||||
|
||||
{
|
||||
const recipient = makeRandomAddress();
|
||||
@ -107,7 +105,7 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
const { accountNumber, sequence } = await client.getNonce();
|
||||
const chainId = await client.getChainId();
|
||||
const signBytes = makeSignBytes([sendMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await pen.sign(signBytes);
|
||||
const signature = await wallet.sign(alice.address0, signBytes);
|
||||
const tx: CosmosSdkTx = {
|
||||
type: "cosmos-sdk/StdTx",
|
||||
value: {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
import { Sha256 } from "@cosmjs/crypto";
|
||||
import { Bech32, fromHex, fromUtf8, toAscii, toBase64 } from "@cosmjs/encoding";
|
||||
import { makeSignBytes, MsgSend, Secp256k1Pen, StdFee } from "@cosmjs/sdk38";
|
||||
import { makeSignBytes, MsgSend, Secp256k1Wallet, StdFee } from "@cosmjs/sdk38";
|
||||
import { assert, sleep } from "@cosmjs/utils";
|
||||
import { ReadonlyDate } from "readonly-date";
|
||||
|
||||
@ -204,7 +204,7 @@ describe("CosmWasmClient", () => {
|
||||
describe("postTx", () => {
|
||||
it("works", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new CosmWasmClient(wasmd.endpoint);
|
||||
|
||||
const memo = "My first contract on chain";
|
||||
@ -235,7 +235,7 @@ describe("CosmWasmClient", () => {
|
||||
const chainId = await client.getChainId();
|
||||
const { accountNumber, sequence } = await client.getNonce(alice.address0);
|
||||
const signBytes = makeSignBytes([sendMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await pen.sign(signBytes);
|
||||
const signature = await wallet.sign(alice.address0, signBytes);
|
||||
const signedTx = {
|
||||
msg: [sendMsg],
|
||||
fee: fee,
|
||||
@ -388,10 +388,8 @@ describe("CosmWasmClient", () => {
|
||||
beforeAll(async () => {
|
||||
if (wasmdEnabled()) {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(wasmd.endpoint, alice.address0, (signBytes) =>
|
||||
pen.sign(signBytes),
|
||||
);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(wasmd.endpoint, alice.address0, wallet);
|
||||
const { codeId } = await client.upload(getHackatom().data);
|
||||
const initMsg = { verifier: makeRandomAddress(), beneficiary: makeRandomAddress() };
|
||||
const { contractAddress } = await client.instantiate(codeId, initMsg, "random hackatom");
|
||||
@ -441,10 +439,8 @@ describe("CosmWasmClient", () => {
|
||||
beforeAll(async () => {
|
||||
if (wasmdEnabled()) {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(wasmd.endpoint, alice.address0, (signBytes) =>
|
||||
pen.sign(signBytes),
|
||||
);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(wasmd.endpoint, alice.address0, wallet);
|
||||
const { codeId } = await client.upload(getHackatom().data);
|
||||
const initMsg = { verifier: makeRandomAddress(), beneficiary: makeRandomAddress() };
|
||||
const { contractAddress } = await client.instantiate(codeId, initMsg, "a different hackatom");
|
||||
|
||||
@ -8,9 +8,9 @@ import {
|
||||
coins,
|
||||
LcdClient,
|
||||
makeSignBytes,
|
||||
Pen,
|
||||
OfflineSigner,
|
||||
PostTxsResponse,
|
||||
Secp256k1Pen,
|
||||
Secp256k1Wallet,
|
||||
setupAuthExtension,
|
||||
StdFee,
|
||||
} from "@cosmjs/sdk38";
|
||||
@ -47,7 +47,7 @@ function makeWasmClient(apiUrl: string): WasmClient {
|
||||
|
||||
async function uploadContract(
|
||||
client: WasmClient,
|
||||
pen: Pen,
|
||||
signer: OfflineSigner,
|
||||
contract: ContractUploadInstructions,
|
||||
): Promise<PostTxsResponse> {
|
||||
const memo = "My first contract on chain";
|
||||
@ -72,14 +72,14 @@ async function uploadContract(
|
||||
|
||||
const { account_number, sequence } = (await client.auth.account(alice.address0)).result.value;
|
||||
const signBytes = makeSignBytes([theMsg], fee, wasmd.chainId, memo, account_number, sequence);
|
||||
const signature = await pen.sign(signBytes);
|
||||
const signature = await signer.sign(alice.address0, signBytes);
|
||||
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
|
||||
return client.postTx(signedTx);
|
||||
}
|
||||
|
||||
async function instantiateContract(
|
||||
client: WasmClient,
|
||||
pen: Pen,
|
||||
signer: OfflineSigner,
|
||||
codeId: number,
|
||||
beneficiaryAddress: string,
|
||||
transferAmount?: readonly Coin[],
|
||||
@ -110,14 +110,14 @@ async function instantiateContract(
|
||||
|
||||
const { account_number, sequence } = (await client.auth.account(alice.address0)).result.value;
|
||||
const signBytes = makeSignBytes([theMsg], fee, wasmd.chainId, memo, account_number, sequence);
|
||||
const signature = await pen.sign(signBytes);
|
||||
const signature = await signer.sign(alice.address0, signBytes);
|
||||
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
|
||||
return client.postTx(signedTx);
|
||||
}
|
||||
|
||||
async function executeContract(
|
||||
client: WasmClient,
|
||||
pen: Pen,
|
||||
signer: OfflineSigner,
|
||||
contractAddress: string,
|
||||
msg: object,
|
||||
): Promise<PostTxsResponse> {
|
||||
@ -138,7 +138,7 @@ async function executeContract(
|
||||
|
||||
const { account_number, sequence } = (await client.auth.account(alice.address0)).result.value;
|
||||
const signBytes = makeSignBytes([theMsg], fee, wasmd.chainId, memo, account_number, sequence);
|
||||
const signature = await pen.sign(signBytes);
|
||||
const signature = await signer.sign(alice.address0, signBytes);
|
||||
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
|
||||
return client.postTx(signedTx);
|
||||
}
|
||||
@ -256,7 +256,7 @@ describe("wasm", () => {
|
||||
describe("postTx", () => {
|
||||
it("can upload, instantiate and execute wasm", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = makeWasmClient(wasmd.endpoint);
|
||||
|
||||
const transferAmount = [coin(1234, "ucosm"), coin(321, "ustake")];
|
||||
@ -267,7 +267,7 @@ describe("wasm", () => {
|
||||
// upload
|
||||
{
|
||||
// console.log("Raw log:", result.raw_log);
|
||||
const result = await uploadContract(client, pen, getHackatom());
|
||||
const result = await uploadContract(client, wallet, getHackatom());
|
||||
expect(result.code).toBeFalsy();
|
||||
const logs = parseLogs(result.logs);
|
||||
const codeIdAttr = findAttribute(logs, "message", "code_id");
|
||||
@ -281,7 +281,7 @@ describe("wasm", () => {
|
||||
|
||||
// instantiate
|
||||
{
|
||||
const result = await instantiateContract(client, pen, codeId, beneficiaryAddress, transferAmount);
|
||||
const result = await instantiateContract(client, wallet, codeId, beneficiaryAddress, transferAmount);
|
||||
expect(result.code).toBeFalsy();
|
||||
// console.log("Raw log:", result.raw_log);
|
||||
const logs = parseLogs(result.logs);
|
||||
@ -297,7 +297,7 @@ describe("wasm", () => {
|
||||
|
||||
// execute
|
||||
{
|
||||
const result = await executeContract(client, pen, contractAddress, { release: {} });
|
||||
const result = await executeContract(client, wallet, contractAddress, { release: {} });
|
||||
expect(result.data).toEqual("F00BAA");
|
||||
expect(result.code).toBeFalsy();
|
||||
// console.log("Raw log:", result.logs);
|
||||
@ -324,7 +324,7 @@ describe("wasm", () => {
|
||||
describe("query", () => {
|
||||
it("can list upload code", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = makeWasmClient(wasmd.endpoint);
|
||||
|
||||
// check with contracts were here first to compare
|
||||
@ -334,7 +334,7 @@ describe("wasm", () => {
|
||||
|
||||
// upload data
|
||||
const hackatom = getHackatom();
|
||||
const result = await uploadContract(client, pen, hackatom);
|
||||
const result = await uploadContract(client, wallet, hackatom);
|
||||
expect(result.code).toBeFalsy();
|
||||
const logs = parseLogs(result.logs);
|
||||
const codeIdAttr = findAttribute(logs, "message", "code_id");
|
||||
@ -362,7 +362,7 @@ describe("wasm", () => {
|
||||
|
||||
it("can list contracts and get info", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = makeWasmClient(wasmd.endpoint);
|
||||
const beneficiaryAddress = makeRandomAddress();
|
||||
const transferAmount: readonly Coin[] = [
|
||||
@ -378,7 +378,7 @@ describe("wasm", () => {
|
||||
if (existingInfos.length > 0) {
|
||||
codeId = existingInfos[existingInfos.length - 1].id;
|
||||
} else {
|
||||
const uploadResult = await uploadContract(client, pen, getHackatom());
|
||||
const uploadResult = await uploadContract(client, wallet, getHackatom());
|
||||
expect(uploadResult.code).toBeFalsy();
|
||||
const uploadLogs = parseLogs(uploadResult.logs);
|
||||
const codeIdAttr = findAttribute(uploadLogs, "message", "code_id");
|
||||
@ -394,7 +394,7 @@ describe("wasm", () => {
|
||||
expect(contract.label).toMatch(/^.+$/);
|
||||
}
|
||||
|
||||
const result = await instantiateContract(client, pen, codeId, beneficiaryAddress, transferAmount);
|
||||
const result = await instantiateContract(client, wallet, codeId, beneficiaryAddress, transferAmount);
|
||||
expect(result.code).toBeFalsy();
|
||||
const logs = parseLogs(result.logs);
|
||||
const contractAddressAttr = findAttribute(logs, "message", "contract_address");
|
||||
@ -438,12 +438,12 @@ describe("wasm", () => {
|
||||
|
||||
beforeAll(async () => {
|
||||
if (wasmdEnabled()) {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const uploadResult = await uploadContract(client, pen, getHackatom());
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const uploadResult = await uploadContract(client, wallet, getHackatom());
|
||||
assert(!uploadResult.code);
|
||||
const uploadLogs = parseLogs(uploadResult.logs);
|
||||
const codeId = Number.parseInt(findAttribute(uploadLogs, "message", "code_id").value, 10);
|
||||
const instantiateResult = await instantiateContract(client, pen, codeId, makeRandomAddress());
|
||||
const instantiateResult = await instantiateContract(client, wallet, codeId, makeRandomAddress());
|
||||
assert(!instantiateResult.code);
|
||||
const instantiateLogs = parseLogs(instantiateResult.logs);
|
||||
const contractAddressAttr = findAttribute(instantiateLogs, "message", "contract_address");
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Sha256 } from "@cosmjs/crypto";
|
||||
import { toHex } from "@cosmjs/encoding";
|
||||
import { AuthExtension, coin, coins, LcdClient, Secp256k1Pen, setupAuthExtension } from "@cosmjs/sdk38";
|
||||
import { AuthExtension, coin, coins, LcdClient, Secp256k1Wallet, setupAuthExtension } from "@cosmjs/sdk38";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
|
||||
import { isPostTxFailure, PrivateCosmWasmClient } from "./cosmwasmclient";
|
||||
@ -17,8 +17,8 @@ function makeWasmClient(apiUrl: string): LcdClient & AuthExtension & WasmExtensi
|
||||
describe("SigningCosmWasmClient", () => {
|
||||
describe("makeReadOnly", () => {
|
||||
it("can be constructed", async () => {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet);
|
||||
expect(client).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@ -26,8 +26,8 @@ describe("SigningCosmWasmClient", () => {
|
||||
describe("getHeight", () => {
|
||||
it("always uses authAccount implementation", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet);
|
||||
|
||||
const openedClient = (client as unknown) as PrivateCosmWasmClient;
|
||||
const blockLatestSpy = spyOn(openedClient.lcdClient, "blocksLatest").and.callThrough();
|
||||
@ -44,8 +44,8 @@ describe("SigningCosmWasmClient", () => {
|
||||
describe("upload", () => {
|
||||
it("works", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet);
|
||||
const wasm = getHackatom().data;
|
||||
const {
|
||||
codeId,
|
||||
@ -63,8 +63,8 @@ describe("SigningCosmWasmClient", () => {
|
||||
|
||||
it("can set builder and source", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet);
|
||||
const hackatom = getHackatom();
|
||||
|
||||
const meta: UploadMeta = {
|
||||
@ -82,8 +82,8 @@ describe("SigningCosmWasmClient", () => {
|
||||
describe("instantiate", () => {
|
||||
it("works with transfer amount", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet);
|
||||
const { codeId } = await client.upload(getHackatom().data);
|
||||
|
||||
const transferAmount = [coin(1234, "ucosm"), coin(321, "ustake")];
|
||||
@ -108,8 +108,8 @@ describe("SigningCosmWasmClient", () => {
|
||||
|
||||
it("works with admin", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet);
|
||||
const { codeId } = await client.upload(getHackatom().data);
|
||||
|
||||
const beneficiaryAddress = makeRandomAddress();
|
||||
@ -131,8 +131,8 @@ describe("SigningCosmWasmClient", () => {
|
||||
|
||||
it("can instantiate one code multiple times", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet);
|
||||
const { codeId } = await client.upload(getHackatom().data);
|
||||
|
||||
const contractAddress1 = await client.instantiate(
|
||||
@ -158,8 +158,8 @@ describe("SigningCosmWasmClient", () => {
|
||||
describe("updateAdmin", () => {
|
||||
it("can update an admin", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet);
|
||||
const { codeId } = await client.upload(getHackatom().data);
|
||||
|
||||
const beneficiaryAddress = makeRandomAddress();
|
||||
@ -191,8 +191,8 @@ describe("SigningCosmWasmClient", () => {
|
||||
describe("clearAdmin", () => {
|
||||
it("can clear an admin", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet);
|
||||
const { codeId } = await client.upload(getHackatom().data);
|
||||
|
||||
const beneficiaryAddress = makeRandomAddress();
|
||||
@ -224,8 +224,8 @@ describe("SigningCosmWasmClient", () => {
|
||||
describe("migrate", () => {
|
||||
it("can can migrate from one code ID to another", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet);
|
||||
const { codeId: codeId1 } = await client.upload(getHackatom().data);
|
||||
const { codeId: codeId2 } = await client.upload(getHackatom().data);
|
||||
|
||||
@ -263,8 +263,8 @@ describe("SigningCosmWasmClient", () => {
|
||||
describe("execute", () => {
|
||||
it("works", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet);
|
||||
const { codeId } = await client.upload(getHackatom().data);
|
||||
|
||||
// instantiate
|
||||
@ -304,8 +304,8 @@ describe("SigningCosmWasmClient", () => {
|
||||
describe("sendTokens", () => {
|
||||
it("works", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet);
|
||||
|
||||
// instantiate
|
||||
const transferAmount = coins(7890, "ucosm");
|
||||
|
||||
@ -7,6 +7,7 @@ import {
|
||||
coins,
|
||||
makeSignBytes,
|
||||
MsgSend,
|
||||
OfflineSigner,
|
||||
StdFee,
|
||||
StdSignature,
|
||||
StdTx,
|
||||
@ -164,7 +165,7 @@ function createPostTxErrorMessage(result: PostTxFailure): string {
|
||||
export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
public readonly senderAddress: string;
|
||||
|
||||
private readonly signCallback: SigningCallback;
|
||||
private readonly signer: OfflineSigner;
|
||||
private readonly fees: FeeTable;
|
||||
|
||||
/**
|
||||
@ -175,14 +176,14 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
*
|
||||
* @param apiUrl The URL of a Cosmos SDK light client daemon API (sometimes called REST server or REST API)
|
||||
* @param senderAddress The address that will sign and send transactions using this instance
|
||||
* @param signCallback An asynchonous callback to create a signature for a given transaction. This can be implemented using secure key stores that require user interaction.
|
||||
* @param signer An implementation of OfflineSigner which can provide signatures for transactions, potentially requiring user input.
|
||||
* @param customFees The fees that are paid for transactions
|
||||
* @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns
|
||||
*/
|
||||
public constructor(
|
||||
apiUrl: string,
|
||||
senderAddress: string,
|
||||
signCallback: SigningCallback,
|
||||
signer: OfflineSigner,
|
||||
customFees?: Partial<FeeTable>,
|
||||
broadcastMode = BroadcastMode.Block,
|
||||
) {
|
||||
@ -190,7 +191,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
this.anyValidAddress = senderAddress;
|
||||
|
||||
this.senderAddress = senderAddress;
|
||||
this.signCallback = signCallback;
|
||||
this.signer = signer;
|
||||
this.fees = { ...defaultFees, ...(customFees || {}) };
|
||||
}
|
||||
|
||||
@ -222,7 +223,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
const { accountNumber, sequence } = await this.getNonce();
|
||||
const chainId = await this.getChainId();
|
||||
const signBytes = makeSignBytes([storeCodeMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await this.signCallback(signBytes);
|
||||
const signature = await this.signer.sign(this.senderAddress, signBytes);
|
||||
const signedTx: StdTx = {
|
||||
msg: [storeCodeMsg],
|
||||
fee: fee,
|
||||
@ -272,7 +273,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
const chainId = await this.getChainId();
|
||||
const signBytes = makeSignBytes([instantiateMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
|
||||
const signature = await this.signCallback(signBytes);
|
||||
const signature = await this.signer.sign(this.senderAddress, signBytes);
|
||||
const signedTx: StdTx = {
|
||||
msg: [instantiateMsg],
|
||||
fee: fee,
|
||||
@ -306,7 +307,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
const { accountNumber, sequence } = await this.getNonce();
|
||||
const chainId = await this.getChainId();
|
||||
const signBytes = makeSignBytes([updateAdminMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await this.signCallback(signBytes);
|
||||
const signature = await this.signer.sign(this.senderAddress, signBytes);
|
||||
const signedTx: StdTx = {
|
||||
msg: [updateAdminMsg],
|
||||
fee: fee,
|
||||
@ -336,7 +337,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
const { accountNumber, sequence } = await this.getNonce();
|
||||
const chainId = await this.getChainId();
|
||||
const signBytes = makeSignBytes([clearAdminMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await this.signCallback(signBytes);
|
||||
const signature = await this.signer.sign(this.senderAddress, signBytes);
|
||||
const signedTx: StdTx = {
|
||||
msg: [clearAdminMsg],
|
||||
fee: fee,
|
||||
@ -374,7 +375,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
const { accountNumber, sequence } = await this.getNonce();
|
||||
const chainId = await this.getChainId();
|
||||
const signBytes = makeSignBytes([msg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await this.signCallback(signBytes);
|
||||
const signature = await this.signer.sign(this.senderAddress, signBytes);
|
||||
const signedTx: StdTx = {
|
||||
msg: [msg],
|
||||
fee: fee,
|
||||
@ -412,7 +413,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
const { accountNumber, sequence } = await this.getNonce();
|
||||
const chainId = await this.getChainId();
|
||||
const signBytes = makeSignBytes([executeMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await this.signCallback(signBytes);
|
||||
const signature = await this.signer.sign(this.senderAddress, signBytes);
|
||||
const signedTx: StdTx = {
|
||||
msg: [executeMsg],
|
||||
fee: fee,
|
||||
@ -449,7 +450,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
const { accountNumber, sequence } = await this.getNonce();
|
||||
const chainId = await this.getChainId();
|
||||
const signBytes = makeSignBytes([sendMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await this.signCallback(signBytes);
|
||||
const signature = await this.signer.sign(this.senderAddress, signBytes);
|
||||
const signedTx: StdTx = {
|
||||
msg: [sendMsg],
|
||||
fee: fee,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { BroadcastMode, Coin, StdFee, StdSignature } from "@cosmjs/sdk38";
|
||||
import { BroadcastMode, Coin, OfflineSigner, StdFee, StdSignature } from "@cosmjs/sdk38";
|
||||
import { Account, CosmWasmClient, GetNonceResult, PostTxResult } from "./cosmwasmclient";
|
||||
import { Log } from "./logs";
|
||||
export interface SigningCallback {
|
||||
@ -83,7 +83,7 @@ export interface ExecuteResult {
|
||||
}
|
||||
export declare class SigningCosmWasmClient extends CosmWasmClient {
|
||||
readonly senderAddress: string;
|
||||
private readonly signCallback;
|
||||
private readonly signer;
|
||||
private readonly fees;
|
||||
/**
|
||||
* Creates a new client with signing capability to interact with a CosmWasm blockchain. This is the bigger brother of CosmWasmClient.
|
||||
@ -93,14 +93,14 @@ export declare class SigningCosmWasmClient extends CosmWasmClient {
|
||||
*
|
||||
* @param apiUrl The URL of a Cosmos SDK light client daemon API (sometimes called REST server or REST API)
|
||||
* @param senderAddress The address that will sign and send transactions using this instance
|
||||
* @param signCallback An asynchonous callback to create a signature for a given transaction. This can be implemented using secure key stores that require user interaction.
|
||||
* @param signer An implementation of OfflineSigner which can provide signatures for transactions, potentially requiring user input.
|
||||
* @param customFees The fees that are paid for transactions
|
||||
* @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns
|
||||
*/
|
||||
constructor(
|
||||
apiUrl: string,
|
||||
senderAddress: string,
|
||||
signCallback: SigningCallback,
|
||||
signer: OfflineSigner,
|
||||
customFees?: Partial<FeeTable>,
|
||||
broadcastMode?: BroadcastMode,
|
||||
);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
import { SigningCosmWasmClient } from "@cosmjs/cosmwasm";
|
||||
import { Coin, coins, makeCosmoshubPath, Secp256k1Pen } from "@cosmjs/sdk38";
|
||||
import { Coin, coins, makeCosmoshubPath, Secp256k1Wallet } from "@cosmjs/sdk38";
|
||||
|
||||
import {
|
||||
BalanceResponse,
|
||||
@ -40,26 +40,19 @@ describe("Staking demo", () => {
|
||||
it("works", async () => {
|
||||
pendingWithoutWasmd();
|
||||
// The owner of the contract that will collect the tax
|
||||
const ownerPen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const ownerAddress = ownerPen.address("cosmos");
|
||||
const ownerClient = new SigningCosmWasmClient(httpUrl, ownerAddress, (signBytes) =>
|
||||
ownerPen.sign(signBytes),
|
||||
);
|
||||
const ownerWallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const [{ address: ownerAddress }] = await ownerWallet.getAccounts();
|
||||
const ownerClient = new SigningCosmWasmClient(httpUrl, ownerAddress, ownerWallet);
|
||||
|
||||
// a user of the contract
|
||||
const userPen = await Secp256k1Pen.fromMnemonic(alice.mnemonic, makeCosmoshubPath(1));
|
||||
const userAddress = userPen.address("cosmos");
|
||||
const userClient = new SigningCosmWasmClient(
|
||||
httpUrl,
|
||||
userAddress,
|
||||
(signBytes) => userPen.sign(signBytes),
|
||||
{
|
||||
exec: {
|
||||
amount: coins(5000, "ucosm"),
|
||||
gas: "300000", // 300k, needed for unbonding
|
||||
},
|
||||
const userWallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic, makeCosmoshubPath(1));
|
||||
const [{ address: userAddress }] = await userWallet.getAccounts();
|
||||
const userClient = new SigningCosmWasmClient(httpUrl, userAddress, userWallet, {
|
||||
exec: {
|
||||
amount: coins(5000, "ucosm"),
|
||||
gas: "300000", // 300k, needed for unbonding
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
const initMsg: InitMsg = {
|
||||
name: params.name,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Bip39, Random } from "@cosmjs/crypto";
|
||||
|
||||
import * as constants from "../constants";
|
||||
import { createPens } from "../profile";
|
||||
import { createWallets } from "../profile";
|
||||
|
||||
export async function generate(args: readonly string[]): Promise<void> {
|
||||
if (args.length < 1) {
|
||||
@ -16,5 +16,5 @@ export async function generate(args: readonly string[]): Promise<void> {
|
||||
console.info(`FAUCET_MNEMONIC="${mnemonic}"`);
|
||||
|
||||
// Log the addresses
|
||||
await createPens(mnemonic, chainId, constants.concurrency, true);
|
||||
await createWallets(mnemonic, chainId, constants.concurrency, true);
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { CosmosClient, Pen, SigningCosmosClient } from "@cosmjs/sdk38";
|
||||
import { CosmosClient, OfflineSigner, SigningCosmosClient } from "@cosmjs/sdk38";
|
||||
import { sleep } from "@cosmjs/utils";
|
||||
|
||||
import { debugAccount, logAccountsState, logSendJob } from "./debugging";
|
||||
import { createPens } from "./profile";
|
||||
import { createWallets } from "./profile";
|
||||
import { TokenManager } from "./tokenmanager";
|
||||
import { MinimalAccount, SendJob, TokenConfiguration } from "./types";
|
||||
|
||||
@ -19,8 +19,8 @@ export class Faucet {
|
||||
numberOfDistributors: number,
|
||||
logging = false,
|
||||
): Promise<Faucet> {
|
||||
const pens = await createPens(mnemonic, addressPrefix, numberOfDistributors, logging);
|
||||
return new Faucet(apiUrl, addressPrefix, config, pens, logging);
|
||||
const wallets = await createWallets(mnemonic, addressPrefix, numberOfDistributors, logging);
|
||||
return new Faucet(apiUrl, addressPrefix, config, wallets, logging);
|
||||
}
|
||||
|
||||
public readonly addressPrefix: string;
|
||||
@ -38,7 +38,7 @@ export class Faucet {
|
||||
apiUrl: string,
|
||||
addressPrefix: string,
|
||||
config: TokenConfiguration,
|
||||
pens: ReadonlyArray<readonly [string, Pen]>,
|
||||
wallets: ReadonlyArray<readonly [string, OfflineSigner]>,
|
||||
logging = false,
|
||||
) {
|
||||
this.addressPrefix = addressPrefix;
|
||||
@ -47,15 +47,13 @@ export class Faucet {
|
||||
|
||||
this.readOnlyClient = new CosmosClient(apiUrl);
|
||||
|
||||
this.holderAddress = pens[0][0];
|
||||
this.distributorAddresses = pens.slice(1).map((pair) => pair[0]);
|
||||
this.holderAddress = wallets[0][0];
|
||||
this.distributorAddresses = wallets.slice(1).map((pair) => pair[0]);
|
||||
|
||||
// we need one client per sender
|
||||
const clients: { [senderAddress: string]: SigningCosmosClient } = {};
|
||||
for (const [senderAddress, pen] of pens) {
|
||||
clients[senderAddress] = new SigningCosmosClient(apiUrl, senderAddress, (signBytes) =>
|
||||
pen.sign(signBytes),
|
||||
);
|
||||
for (const [senderAddress, wallet] of wallets) {
|
||||
clients[senderAddress] = new SigningCosmosClient(apiUrl, senderAddress, wallet);
|
||||
}
|
||||
this.clients = clients;
|
||||
this.logging = logging;
|
||||
|
||||
@ -1,26 +1,26 @@
|
||||
import { pathToString } from "@cosmjs/crypto";
|
||||
import { makeCosmoshubPath, Pen, Secp256k1Pen } from "@cosmjs/sdk38";
|
||||
import { makeCosmoshubPath, OfflineSigner, Secp256k1Wallet } from "@cosmjs/sdk38";
|
||||
|
||||
export async function createPens(
|
||||
export async function createWallets(
|
||||
mnemonic: string,
|
||||
addressPrefix: string,
|
||||
numberOfDistributors: number,
|
||||
logging = false,
|
||||
): Promise<ReadonlyArray<readonly [string, Pen]>> {
|
||||
const pens = new Array<readonly [string, Pen]>();
|
||||
): Promise<ReadonlyArray<readonly [string, OfflineSigner]>> {
|
||||
const wallets = new Array<readonly [string, OfflineSigner]>();
|
||||
|
||||
// first account is the token holder
|
||||
const numberOfIdentities = 1 + numberOfDistributors;
|
||||
for (let i = 0; i < numberOfIdentities; i++) {
|
||||
const path = makeCosmoshubPath(i);
|
||||
const pen = await Secp256k1Pen.fromMnemonic(mnemonic, path);
|
||||
const address = pen.address(addressPrefix);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(mnemonic, path, addressPrefix);
|
||||
const [{ address }] = await wallet.getAccounts();
|
||||
if (logging) {
|
||||
const role = i === 0 ? "token holder " : `distributor ${i}`;
|
||||
console.info(`Created ${role} (${pathToString(path)}): ${address}`);
|
||||
}
|
||||
pens.push([address, pen]);
|
||||
wallets.push([address, wallet]);
|
||||
}
|
||||
|
||||
return pens;
|
||||
return wallets;
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import { CosmosClient, isPostTxFailure } from "./cosmosclient";
|
||||
import { makeSignBytes } from "./encoding";
|
||||
import { LcdClient } from "./lcdapi";
|
||||
import { isMsgSend, MsgSend } from "./msgs";
|
||||
import { Secp256k1Pen } from "./pen";
|
||||
import { SigningCosmosClient } from "./signingcosmosclient";
|
||||
import {
|
||||
faucet,
|
||||
@ -17,6 +16,7 @@ import {
|
||||
wasmdEnabled,
|
||||
} from "./testutils.spec";
|
||||
import { CosmosSdkTx } from "./types";
|
||||
import { Secp256k1Wallet } from "./wallet";
|
||||
|
||||
interface TestTxSend {
|
||||
readonly sender: string;
|
||||
@ -32,10 +32,10 @@ describe("CosmosClient.searchTx", () => {
|
||||
|
||||
beforeAll(async () => {
|
||||
if (wasmdEnabled()) {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic);
|
||||
const client = new SigningCosmosClient(wasmd.endpoint, faucet.address, (signBytes) =>
|
||||
pen.sign(signBytes),
|
||||
);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic);
|
||||
const accounts = await wallet.getAccounts();
|
||||
const [{ address: walletAddress }] = accounts;
|
||||
const client = new SigningCosmosClient(wasmd.endpoint, faucet.address, wallet);
|
||||
|
||||
{
|
||||
const memo = "Sending more than I can afford";
|
||||
@ -58,7 +58,7 @@ describe("CosmosClient.searchTx", () => {
|
||||
const { accountNumber, sequence } = await client.getNonce();
|
||||
const chainId = await client.getChainId();
|
||||
const signBytes = makeSignBytes([sendMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await pen.sign(signBytes);
|
||||
const signature = await wallet.sign(walletAddress, signBytes);
|
||||
const tx: CosmosSdkTx = {
|
||||
type: "cosmos-sdk/StdTx",
|
||||
value: {
|
||||
|
||||
@ -6,7 +6,6 @@ import { CosmosClient, isPostTxFailure, PrivateCosmWasmClient } from "./cosmoscl
|
||||
import { makeSignBytes } from "./encoding";
|
||||
import { findAttribute } from "./logs";
|
||||
import { MsgSend } from "./msgs";
|
||||
import { Secp256k1Pen } from "./pen";
|
||||
import cosmoshub from "./testdata/cosmoshub.json";
|
||||
import {
|
||||
faucet,
|
||||
@ -17,6 +16,7 @@ import {
|
||||
wasmd,
|
||||
} from "./testutils.spec";
|
||||
import { StdFee } from "./types";
|
||||
import { Secp256k1Wallet } from "./wallet";
|
||||
|
||||
const blockTime = 1_000; // ms
|
||||
|
||||
@ -193,7 +193,9 @@ describe("CosmosClient", () => {
|
||||
describe("postTx", () => {
|
||||
it("works", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic);
|
||||
const accounts = await wallet.getAccounts();
|
||||
const [{ address: walletAddress }] = accounts;
|
||||
const client = new CosmosClient(wasmd.endpoint);
|
||||
|
||||
const memo = "My first contract on chain";
|
||||
@ -224,7 +226,7 @@ describe("CosmosClient", () => {
|
||||
const chainId = await client.getChainId();
|
||||
const { accountNumber, sequence } = await client.getNonce(faucet.address);
|
||||
const signBytes = makeSignBytes([sendMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await pen.sign(signBytes);
|
||||
const signature = await wallet.sign(walletAddress, signBytes);
|
||||
const signedTx = {
|
||||
msg: [sendMsg],
|
||||
fee: fee,
|
||||
|
||||
@ -50,9 +50,9 @@ export {
|
||||
TxsResponse,
|
||||
} from "./lcdapi";
|
||||
export { isMsgDelegate, isMsgSend, Msg, MsgDelegate, MsgSend } from "./msgs";
|
||||
export { Pen, Secp256k1Pen, makeCosmoshubPath } from "./pen";
|
||||
export { decodeBech32Pubkey, encodeBech32Pubkey, encodeSecp256k1Pubkey } from "./pubkey";
|
||||
export { findSequenceForSignedTx } from "./sequence";
|
||||
export { encodeSecp256k1Signature, decodeSignature } from "./signature";
|
||||
export { FeeTable, SigningCallback, SigningCosmosClient } from "./signingcosmosclient";
|
||||
export { FeeTable, SigningCosmosClient } from "./signingcosmosclient";
|
||||
export { isStdTx, pubkeyType, CosmosSdkTx, PubKey, StdFee, StdSignature, StdTx } from "./types";
|
||||
export { OfflineSigner, Secp256k1Wallet, makeCosmoshubPath } from "./wallet";
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
import { assert, sleep } from "@cosmjs/utils";
|
||||
|
||||
import { rawSecp256k1PubkeyToAddress } from "../address";
|
||||
import { Coin } from "../coins";
|
||||
import { isPostTxFailure } from "../cosmosclient";
|
||||
import { makeSignBytes } from "../encoding";
|
||||
import { parseLogs } from "../logs";
|
||||
import { MsgSend } from "../msgs";
|
||||
import { makeCosmoshubPath, Secp256k1Pen } from "../pen";
|
||||
import { SigningCosmosClient } from "../signingcosmosclient";
|
||||
import cosmoshub from "../testdata/cosmoshub.json";
|
||||
import {
|
||||
@ -21,6 +19,7 @@ import {
|
||||
wasmdEnabled,
|
||||
} from "../testutils.spec";
|
||||
import { StdFee } from "../types";
|
||||
import { makeCosmoshubPath, Secp256k1Wallet } from "../wallet";
|
||||
import { setupAuthExtension } from "./auth";
|
||||
import { TxsResponse } from "./base";
|
||||
import { LcdApiArray, LcdClient, normalizeLcdApiArray } from "./lcdclient";
|
||||
@ -217,10 +216,10 @@ describe("LcdClient", () => {
|
||||
|
||||
beforeAll(async () => {
|
||||
if (wasmdEnabled()) {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic);
|
||||
const client = new SigningCosmosClient(wasmd.endpoint, faucet.address, (signBytes) =>
|
||||
pen.sign(signBytes),
|
||||
);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic);
|
||||
const accounts = await wallet.getAccounts();
|
||||
const [{ address: walletAddress }] = accounts;
|
||||
const client = new SigningCosmosClient(wasmd.endpoint, faucet.address, wallet);
|
||||
|
||||
{
|
||||
const recipient = makeRandomAddress();
|
||||
@ -267,7 +266,7 @@ describe("LcdClient", () => {
|
||||
const { accountNumber, sequence } = await client.getNonce();
|
||||
const chainId = await client.getChainId();
|
||||
const signBytes = makeSignBytes([sendMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await pen.sign(signBytes);
|
||||
const signature = await wallet.sign(walletAddress, signBytes);
|
||||
const signedTx = {
|
||||
msg: [sendMsg],
|
||||
fee: fee,
|
||||
@ -351,10 +350,8 @@ describe("LcdClient", () => {
|
||||
|
||||
beforeAll(async () => {
|
||||
if (wasmdEnabled()) {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic);
|
||||
const client = new SigningCosmosClient(wasmd.endpoint, faucet.address, (signBytes) =>
|
||||
pen.sign(signBytes),
|
||||
);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic);
|
||||
const client = new SigningCosmosClient(wasmd.endpoint, faucet.address, wallet);
|
||||
|
||||
const recipient = makeRandomAddress();
|
||||
const transferAmount = [
|
||||
@ -534,7 +531,9 @@ describe("LcdClient", () => {
|
||||
describe("postTx", () => {
|
||||
it("can send tokens", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic);
|
||||
const accounts = await wallet.getAccounts();
|
||||
const [{ address: walletAddress }] = accounts;
|
||||
|
||||
const memo = "My first contract on chain";
|
||||
const theMsg: MsgSend = {
|
||||
@ -565,7 +564,7 @@ describe("LcdClient", () => {
|
||||
const { account_number, sequence } = (await client.auth.account(faucet.address)).result.value;
|
||||
|
||||
const signBytes = makeSignBytes([theMsg], fee, wasmd.chainId, memo, account_number, sequence);
|
||||
const signature = await pen.sign(signBytes);
|
||||
const signature = await wallet.sign(walletAddress, signBytes);
|
||||
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
|
||||
const result = await client.postTx(signedTx);
|
||||
expect(result.code).toBeUndefined();
|
||||
@ -582,12 +581,14 @@ describe("LcdClient", () => {
|
||||
|
||||
it("can't send transaction with additional signatures", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const account1 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0));
|
||||
const account2 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(1));
|
||||
const account3 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(2));
|
||||
const address1 = rawSecp256k1PubkeyToAddress(account1.pubkey, "cosmos");
|
||||
const address2 = rawSecp256k1PubkeyToAddress(account2.pubkey, "cosmos");
|
||||
const address3 = rawSecp256k1PubkeyToAddress(account3.pubkey, "cosmos");
|
||||
const account1 = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0));
|
||||
const account2 = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(1));
|
||||
const account3 = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(2));
|
||||
const [address1, address2, address3] = await Promise.all(
|
||||
[account1, account2, account3].map(async (wallet) => {
|
||||
return (await wallet.getAccounts())[0].address;
|
||||
}),
|
||||
);
|
||||
|
||||
const memo = "My first contract on chain";
|
||||
const theMsg: MsgSend = {
|
||||
@ -622,9 +623,9 @@ describe("LcdClient", () => {
|
||||
const signBytes1 = makeSignBytes([theMsg], fee, wasmd.chainId, memo, an1, sequence1);
|
||||
const signBytes2 = makeSignBytes([theMsg], fee, wasmd.chainId, memo, an2, sequence2);
|
||||
const signBytes3 = makeSignBytes([theMsg], fee, wasmd.chainId, memo, an3, sequence3);
|
||||
const signature1 = await account1.sign(signBytes1);
|
||||
const signature2 = await account2.sign(signBytes2);
|
||||
const signature3 = await account3.sign(signBytes3);
|
||||
const signature1 = await account1.sign(address1, signBytes1);
|
||||
const signature2 = await account2.sign(address2, signBytes2);
|
||||
const signature3 = await account3.sign(address3, signBytes3);
|
||||
const signedTx = {
|
||||
msg: [theMsg],
|
||||
fee: fee,
|
||||
@ -638,14 +639,15 @@ describe("LcdClient", () => {
|
||||
|
||||
it("can send multiple messages with one signature", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const account1 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0));
|
||||
const address1 = rawSecp256k1PubkeyToAddress(account1.pubkey, "cosmos");
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0));
|
||||
const accounts = await wallet.getAccounts();
|
||||
const [{ address: walletAddress }] = accounts;
|
||||
|
||||
const memo = "My first contract on chain";
|
||||
const msg1: MsgSend = {
|
||||
type: "cosmos-sdk/MsgSend",
|
||||
value: {
|
||||
from_address: address1,
|
||||
from_address: walletAddress,
|
||||
to_address: defaultRecipientAddress,
|
||||
amount: [
|
||||
{
|
||||
@ -658,7 +660,7 @@ describe("LcdClient", () => {
|
||||
const msg2: MsgSend = {
|
||||
type: "cosmos-sdk/MsgSend",
|
||||
value: {
|
||||
from_address: address1,
|
||||
from_address: walletAddress,
|
||||
to_address: defaultRecipientAddress,
|
||||
amount: [
|
||||
{
|
||||
@ -680,10 +682,10 @@ describe("LcdClient", () => {
|
||||
};
|
||||
|
||||
const client = LcdClient.withExtensions({ apiUrl: wasmd.endpoint }, setupAuthExtension);
|
||||
const { account_number, sequence } = (await client.auth.account(address1)).result.value;
|
||||
const { account_number, sequence } = (await client.auth.account(walletAddress)).result.value;
|
||||
|
||||
const signBytes = makeSignBytes([msg1, msg2], fee, wasmd.chainId, memo, account_number, sequence);
|
||||
const signature1 = await account1.sign(signBytes);
|
||||
const signature1 = await wallet.sign(walletAddress, signBytes);
|
||||
const signedTx = {
|
||||
msg: [msg1, msg2],
|
||||
fee: fee,
|
||||
@ -696,10 +698,13 @@ describe("LcdClient", () => {
|
||||
|
||||
it("can send multiple messages with multiple signatures", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const account1 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0));
|
||||
const account2 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(1));
|
||||
const address1 = rawSecp256k1PubkeyToAddress(account1.pubkey, "cosmos");
|
||||
const address2 = rawSecp256k1PubkeyToAddress(account2.pubkey, "cosmos");
|
||||
const account1 = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0));
|
||||
const account2 = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(1));
|
||||
const [address1, address2] = await Promise.all(
|
||||
[account1, account2].map(async (wallet) => {
|
||||
return (await wallet.getAccounts())[0].address;
|
||||
}),
|
||||
);
|
||||
|
||||
const memo = "My first contract on chain";
|
||||
const msg1: MsgSend = {
|
||||
@ -745,8 +750,8 @@ describe("LcdClient", () => {
|
||||
|
||||
const signBytes1 = makeSignBytes([msg2, msg1], fee, wasmd.chainId, memo, an1, sequence1);
|
||||
const signBytes2 = makeSignBytes([msg2, msg1], fee, wasmd.chainId, memo, an2, sequence2);
|
||||
const signature1 = await account1.sign(signBytes1);
|
||||
const signature2 = await account2.sign(signBytes2);
|
||||
const signature1 = await account1.sign(address1, signBytes1);
|
||||
const signature2 = await account2.sign(address2, signBytes2);
|
||||
const signedTx = {
|
||||
msg: [msg2, msg1],
|
||||
fee: fee,
|
||||
@ -764,10 +769,13 @@ describe("LcdClient", () => {
|
||||
|
||||
it("can't send transaction with wrong signature order (1)", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const account1 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0));
|
||||
const account2 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(1));
|
||||
const address1 = rawSecp256k1PubkeyToAddress(account1.pubkey, "cosmos");
|
||||
const address2 = rawSecp256k1PubkeyToAddress(account2.pubkey, "cosmos");
|
||||
const account1 = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0));
|
||||
const account2 = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(1));
|
||||
const [address1, address2] = await Promise.all(
|
||||
[account1, account2].map(async (wallet) => {
|
||||
return (await wallet.getAccounts())[0].address;
|
||||
}),
|
||||
);
|
||||
|
||||
const memo = "My first contract on chain";
|
||||
const msg1: MsgSend = {
|
||||
@ -813,8 +821,8 @@ describe("LcdClient", () => {
|
||||
|
||||
const signBytes1 = makeSignBytes([msg1, msg2], fee, wasmd.chainId, memo, an1, sequence1);
|
||||
const signBytes2 = makeSignBytes([msg1, msg2], fee, wasmd.chainId, memo, an2, sequence2);
|
||||
const signature1 = await account1.sign(signBytes1);
|
||||
const signature2 = await account2.sign(signBytes2);
|
||||
const signature1 = await account1.sign(address1, signBytes1);
|
||||
const signature2 = await account2.sign(address2, signBytes2);
|
||||
const signedTx = {
|
||||
msg: [msg1, msg2],
|
||||
fee: fee,
|
||||
@ -827,10 +835,13 @@ describe("LcdClient", () => {
|
||||
|
||||
it("can't send transaction with wrong signature order (2)", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const account1 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0));
|
||||
const account2 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(1));
|
||||
const address1 = rawSecp256k1PubkeyToAddress(account1.pubkey, "cosmos");
|
||||
const address2 = rawSecp256k1PubkeyToAddress(account2.pubkey, "cosmos");
|
||||
const account1 = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0));
|
||||
const account2 = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(1));
|
||||
const [address1, address2] = await Promise.all(
|
||||
[account1, account2].map(async (wallet) => {
|
||||
return (await wallet.getAccounts())[0].address;
|
||||
}),
|
||||
);
|
||||
|
||||
const memo = "My first contract on chain";
|
||||
const msg1: MsgSend = {
|
||||
@ -876,8 +887,8 @@ describe("LcdClient", () => {
|
||||
|
||||
const signBytes1 = makeSignBytes([msg2, msg1], fee, wasmd.chainId, memo, an1, sequence1);
|
||||
const signBytes2 = makeSignBytes([msg2, msg1], fee, wasmd.chainId, memo, an2, sequence2);
|
||||
const signature1 = await account1.sign(signBytes1);
|
||||
const signature2 = await account2.sign(signBytes2);
|
||||
const signature1 = await account1.sign(address1, signBytes1);
|
||||
const signature2 = await account2.sign(address2, signBytes2);
|
||||
const signedTx = {
|
||||
msg: [msg2, msg1],
|
||||
fee: fee,
|
||||
|
||||
@ -1,54 +0,0 @@
|
||||
import { Secp256k1, Secp256k1Signature, Sha256 } from "@cosmjs/crypto";
|
||||
import { fromHex, toAscii } from "@cosmjs/encoding";
|
||||
|
||||
import { Secp256k1Pen } from "./pen";
|
||||
import { decodeSignature } from "./signature";
|
||||
|
||||
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("sign", () => {
|
||||
it("creates correct signatures", async () => {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(
|
||||
"special sign fit simple patrol salute grocery chicken wheat radar tonight ceiling",
|
||||
);
|
||||
const data = toAscii("foo bar");
|
||||
const { pubkey, signature } = decodeSignature(await pen.sign(data));
|
||||
|
||||
const valid = await Secp256k1.verifySignature(
|
||||
Secp256k1Signature.fromFixedLength(signature),
|
||||
new Sha256(data).digest(),
|
||||
pubkey,
|
||||
);
|
||||
expect(valid).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("address", () => {
|
||||
it("creates same address as Go imlementation", async () => {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(
|
||||
"oyster design unusual machine spread century engine gravity focus cave carry slot",
|
||||
);
|
||||
expect(pen.address("cosmos")).toEqual("cosmos1cjsxept9rkggzxztslae9ndgpdyt2408lk850u");
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,92 +0,0 @@
|
||||
import {
|
||||
Bip39,
|
||||
EnglishMnemonic,
|
||||
Secp256k1,
|
||||
Sha256,
|
||||
Sha512,
|
||||
Slip10,
|
||||
Slip10Curve,
|
||||
Slip10RawIndex,
|
||||
} from "@cosmjs/crypto";
|
||||
|
||||
import { rawSecp256k1PubkeyToAddress } from "./address";
|
||||
import { encodeSecp256k1Signature } from "./signature";
|
||||
import { StdSignature } from "./types";
|
||||
|
||||
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 sign: (signBytes: Uint8Array, prehashType?: PrehashType) => Promise<StdSignature>;
|
||||
}
|
||||
|
||||
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 and returns a signature
|
||||
*/
|
||||
public async sign(signBytes: Uint8Array, prehashType: PrehashType = "sha256"): Promise<StdSignature> {
|
||||
const message = prehash(signBytes, prehashType);
|
||||
const signature = await Secp256k1.createSignature(message, this.privkey);
|
||||
const fixedLengthSignature = new Uint8Array([...signature.r(32), ...signature.s(32)]);
|
||||
return encodeSecp256k1Signature(this.pubkey, fixedLengthSignature);
|
||||
}
|
||||
|
||||
public address(prefix: string): string {
|
||||
return rawSecp256k1PubkeyToAddress(this.pubkey, prefix);
|
||||
}
|
||||
}
|
||||
@ -2,9 +2,9 @@ import { assert } from "@cosmjs/utils";
|
||||
|
||||
import { Coin } from "./coins";
|
||||
import { isPostTxFailure, PrivateCosmWasmClient } from "./cosmosclient";
|
||||
import { Secp256k1Pen } from "./pen";
|
||||
import { SigningCosmosClient } from "./signingcosmosclient";
|
||||
import { makeRandomAddress, pendingWithoutWasmd } from "./testutils.spec";
|
||||
import { Secp256k1Wallet } from "./wallet";
|
||||
|
||||
const httpUrl = "http://localhost:1317";
|
||||
|
||||
@ -21,8 +21,8 @@ const faucet = {
|
||||
describe("SigningCosmosClient", () => {
|
||||
describe("makeReadOnly", () => {
|
||||
it("can be constructed", async () => {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic);
|
||||
const client = new SigningCosmosClient(httpUrl, faucet.address, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic);
|
||||
const client = new SigningCosmosClient(httpUrl, faucet.address, wallet);
|
||||
expect(client).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@ -30,8 +30,8 @@ describe("SigningCosmosClient", () => {
|
||||
describe("getHeight", () => {
|
||||
it("always uses authAccount implementation", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic);
|
||||
const client = new SigningCosmosClient(httpUrl, faucet.address, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic);
|
||||
const client = new SigningCosmosClient(httpUrl, faucet.address, wallet);
|
||||
|
||||
const openedClient = (client as unknown) as PrivateCosmWasmClient;
|
||||
const blockLatestSpy = spyOn(openedClient.lcdClient, "blocksLatest").and.callThrough();
|
||||
@ -48,8 +48,8 @@ describe("SigningCosmosClient", () => {
|
||||
describe("sendTokens", () => {
|
||||
it("works", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic);
|
||||
const client = new SigningCosmosClient(httpUrl, faucet.address, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic);
|
||||
const client = new SigningCosmosClient(httpUrl, faucet.address, wallet);
|
||||
|
||||
// instantiate
|
||||
const transferAmount: readonly Coin[] = [
|
||||
|
||||
@ -3,11 +3,8 @@ import { Account, CosmosClient, GetNonceResult, PostTxResult } from "./cosmoscli
|
||||
import { makeSignBytes } from "./encoding";
|
||||
import { BroadcastMode } from "./lcdapi";
|
||||
import { MsgSend } from "./msgs";
|
||||
import { StdFee, StdSignature, StdTx } from "./types";
|
||||
|
||||
export interface SigningCallback {
|
||||
(signBytes: Uint8Array): Promise<StdSignature>;
|
||||
}
|
||||
import { StdFee, StdTx } from "./types";
|
||||
import { OfflineSigner } from "./wallet";
|
||||
|
||||
export interface FeeTable {
|
||||
readonly upload: StdFee;
|
||||
@ -38,7 +35,7 @@ const defaultFees: FeeTable = {
|
||||
export class SigningCosmosClient extends CosmosClient {
|
||||
public readonly senderAddress: string;
|
||||
|
||||
private readonly signCallback: SigningCallback;
|
||||
private readonly signer: OfflineSigner;
|
||||
private readonly fees: FeeTable;
|
||||
|
||||
/**
|
||||
@ -49,14 +46,14 @@ export class SigningCosmosClient extends CosmosClient {
|
||||
*
|
||||
* @param apiUrl The URL of a Cosmos SDK light client daemon API (sometimes called REST server or REST API)
|
||||
* @param senderAddress The address that will sign and send transactions using this instance
|
||||
* @param signCallback An asynchonous callback to create a signature for a given transaction. This can be implemented using secure key stores that require user interaction.
|
||||
* @param signer An implementation of OfflineSigner which can provide signatures for transactions, potentially requiring user input.
|
||||
* @param customFees The fees that are paid for transactions
|
||||
* @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns
|
||||
*/
|
||||
public constructor(
|
||||
apiUrl: string,
|
||||
senderAddress: string,
|
||||
signCallback: SigningCallback,
|
||||
signer: OfflineSigner,
|
||||
customFees?: Partial<FeeTable>,
|
||||
broadcastMode = BroadcastMode.Block,
|
||||
) {
|
||||
@ -64,7 +61,7 @@ export class SigningCosmosClient extends CosmosClient {
|
||||
this.anyValidAddress = senderAddress;
|
||||
|
||||
this.senderAddress = senderAddress;
|
||||
this.signCallback = signCallback;
|
||||
this.signer = signer;
|
||||
this.fees = { ...defaultFees, ...(customFees || {}) };
|
||||
}
|
||||
|
||||
@ -95,7 +92,7 @@ export class SigningCosmosClient extends CosmosClient {
|
||||
const { accountNumber, sequence } = await this.getNonce();
|
||||
const chainId = await this.getChainId();
|
||||
const signBytes = makeSignBytes([sendMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await this.signCallback(signBytes);
|
||||
const signature = await this.signer.sign(this.senderAddress, signBytes);
|
||||
const signedTx: StdTx = {
|
||||
msg: [sendMsg],
|
||||
fee: fee,
|
||||
|
||||
52
packages/sdk38/src/wallet.spec.ts
Normal file
52
packages/sdk38/src/wallet.spec.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { Secp256k1, Secp256k1Signature, Sha256 } from "@cosmjs/crypto";
|
||||
import { fromBase64, fromHex, toAscii } from "@cosmjs/encoding";
|
||||
|
||||
import { Secp256k1Wallet } from "./wallet";
|
||||
|
||||
describe("Secp256k1Wallet", () => {
|
||||
// m/44'/118'/0'/0/0
|
||||
// pubkey: 02baa4ef93f2ce84592a49b1d729c074eab640112522a7a89f7d03ebab21ded7b6
|
||||
const defaultMnemonic = "special sign fit simple patrol salute grocery chicken wheat radar tonight ceiling";
|
||||
const defaultPubkey = fromHex("02baa4ef93f2ce84592a49b1d729c074eab640112522a7a89f7d03ebab21ded7b6");
|
||||
const defaultAddress = "cosmos1jhg0e7s6gn44tfc5k37kr04sznyhedtc9rzys5";
|
||||
|
||||
it("can be constructed", async () => {
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(defaultMnemonic);
|
||||
expect(wallet).toBeTruthy();
|
||||
});
|
||||
|
||||
describe("getAccounts", () => {
|
||||
it("resolves to a list of accounts if enabled", async () => {
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(defaultMnemonic);
|
||||
const accounts = await wallet.getAccounts();
|
||||
expect(accounts.length).toEqual(1);
|
||||
expect(accounts[0]).toEqual({
|
||||
address: defaultAddress,
|
||||
algo: "secp256k1",
|
||||
pubkey: defaultPubkey,
|
||||
});
|
||||
});
|
||||
|
||||
it("creates the same address as Go implementation", async () => {
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(
|
||||
"oyster design unusual machine spread century engine gravity focus cave carry slot",
|
||||
);
|
||||
const [{ address }] = await wallet.getAccounts();
|
||||
expect(address).toEqual("cosmos1cjsxept9rkggzxztslae9ndgpdyt2408lk850u");
|
||||
});
|
||||
});
|
||||
|
||||
describe("sign", () => {
|
||||
it("resolves to valid signature if enabled", async () => {
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(defaultMnemonic);
|
||||
const message = toAscii("foo bar");
|
||||
const signature = await wallet.sign(defaultAddress, message);
|
||||
const valid = await Secp256k1.verifySignature(
|
||||
Secp256k1Signature.fromFixedLength(fromBase64(signature.signature)),
|
||||
new Sha256(message).digest(),
|
||||
defaultPubkey,
|
||||
);
|
||||
expect(valid).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
116
packages/sdk38/src/wallet.ts
Normal file
116
packages/sdk38/src/wallet.ts
Normal file
@ -0,0 +1,116 @@
|
||||
import {
|
||||
Bip39,
|
||||
EnglishMnemonic,
|
||||
Secp256k1,
|
||||
Sha256,
|
||||
Sha512,
|
||||
Slip10,
|
||||
Slip10Curve,
|
||||
Slip10RawIndex,
|
||||
} from "@cosmjs/crypto";
|
||||
|
||||
import { rawSecp256k1PubkeyToAddress } from "./address";
|
||||
import { encodeSecp256k1Signature } from "./signature";
|
||||
import { StdSignature } from "./types";
|
||||
|
||||
export type PrehashType = "sha256" | "sha512" | null;
|
||||
|
||||
export type Algo = "secp256k1" | "ed25519" | "sr25519";
|
||||
|
||||
export interface AccountData {
|
||||
// bech32-encoded
|
||||
readonly address: string;
|
||||
readonly algo: Algo;
|
||||
readonly pubkey: Uint8Array;
|
||||
}
|
||||
|
||||
export interface OfflineSigner {
|
||||
/**
|
||||
* Get AccountData array from wallet. Rejects if not enabled.
|
||||
*/
|
||||
readonly getAccounts: () => Promise<readonly AccountData[]>;
|
||||
|
||||
/**
|
||||
* Request signature from whichever key corresponds to provided bech32-encoded address. Rejects if not enabled.
|
||||
*/
|
||||
readonly sign: (address: string, message: Uint8Array, prehashType?: PrehashType) => Promise<StdSignature>;
|
||||
}
|
||||
|
||||
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 Secp256k1Wallet implements OfflineSigner {
|
||||
public static async fromMnemonic(
|
||||
mnemonic: string,
|
||||
hdPath: readonly Slip10RawIndex[] = makeCosmoshubPath(0),
|
||||
prefix = "cosmos",
|
||||
): Promise<Secp256k1Wallet> {
|
||||
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 Secp256k1Wallet(privkey, Secp256k1.compressPubkey(uncompressed), prefix);
|
||||
}
|
||||
|
||||
private readonly pubkey: Uint8Array;
|
||||
private readonly privkey: Uint8Array;
|
||||
private readonly prefix: string;
|
||||
private readonly algo: Algo = "secp256k1";
|
||||
|
||||
private constructor(privkey: Uint8Array, pubkey: Uint8Array, prefix: string) {
|
||||
this.privkey = privkey;
|
||||
this.pubkey = pubkey;
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
private get address(): string {
|
||||
return rawSecp256k1PubkeyToAddress(this.pubkey, this.prefix);
|
||||
}
|
||||
|
||||
public async getAccounts(): Promise<readonly AccountData[]> {
|
||||
return [
|
||||
{
|
||||
address: this.address,
|
||||
algo: this.algo,
|
||||
pubkey: this.pubkey,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
public async sign(
|
||||
address: string,
|
||||
message: Uint8Array,
|
||||
prehashType: PrehashType = "sha256",
|
||||
): Promise<StdSignature> {
|
||||
if (address !== this.address) {
|
||||
throw new Error(`Address ${address} not found in wallet`);
|
||||
}
|
||||
const hashedMessage = prehash(message, prehashType);
|
||||
const signature = await Secp256k1.createSignature(hashedMessage, this.privkey);
|
||||
const signatureBytes = new Uint8Array([...signature.r(32), ...signature.s(32)]);
|
||||
return encodeSecp256k1Signature(this.pubkey, signatureBytes);
|
||||
}
|
||||
}
|
||||
4
packages/sdk38/types/index.d.ts
vendored
4
packages/sdk38/types/index.d.ts
vendored
@ -48,9 +48,9 @@ export {
|
||||
TxsResponse,
|
||||
} from "./lcdapi";
|
||||
export { isMsgDelegate, isMsgSend, Msg, MsgDelegate, MsgSend } from "./msgs";
|
||||
export { Pen, Secp256k1Pen, makeCosmoshubPath } from "./pen";
|
||||
export { decodeBech32Pubkey, encodeBech32Pubkey, encodeSecp256k1Pubkey } from "./pubkey";
|
||||
export { findSequenceForSignedTx } from "./sequence";
|
||||
export { encodeSecp256k1Signature, decodeSignature } from "./signature";
|
||||
export { FeeTable, SigningCallback, SigningCosmosClient } from "./signingcosmosclient";
|
||||
export { FeeTable, SigningCosmosClient } from "./signingcosmosclient";
|
||||
export { isStdTx, pubkeyType, CosmosSdkTx, PubKey, StdFee, StdSignature, StdTx } from "./types";
|
||||
export { OfflineSigner, Secp256k1Wallet, makeCosmoshubPath } from "./wallet";
|
||||
|
||||
33
packages/sdk38/types/pen.d.ts
vendored
33
packages/sdk38/types/pen.d.ts
vendored
@ -1,33 +0,0 @@
|
||||
import { Slip10RawIndex } from "@cosmjs/crypto";
|
||||
import { StdSignature } from "./types";
|
||||
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 sign: (signBytes: Uint8Array, prehashType?: PrehashType) => Promise<StdSignature>;
|
||||
}
|
||||
/**
|
||||
* 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 and returns a signature
|
||||
*/
|
||||
sign(signBytes: Uint8Array, prehashType?: PrehashType): Promise<StdSignature>;
|
||||
address(prefix: string): string;
|
||||
}
|
||||
12
packages/sdk38/types/signingcosmosclient.d.ts
vendored
12
packages/sdk38/types/signingcosmosclient.d.ts
vendored
@ -1,10 +1,8 @@
|
||||
import { Coin } from "./coins";
|
||||
import { Account, CosmosClient, GetNonceResult, PostTxResult } from "./cosmosclient";
|
||||
import { BroadcastMode } from "./lcdapi";
|
||||
import { StdFee, StdSignature } from "./types";
|
||||
export interface SigningCallback {
|
||||
(signBytes: Uint8Array): Promise<StdSignature>;
|
||||
}
|
||||
import { StdFee } from "./types";
|
||||
import { OfflineSigner } from "./wallet";
|
||||
export interface FeeTable {
|
||||
readonly upload: StdFee;
|
||||
readonly init: StdFee;
|
||||
@ -13,7 +11,7 @@ export interface FeeTable {
|
||||
}
|
||||
export declare class SigningCosmosClient extends CosmosClient {
|
||||
readonly senderAddress: string;
|
||||
private readonly signCallback;
|
||||
private readonly signer;
|
||||
private readonly fees;
|
||||
/**
|
||||
* Creates a new client with signing capability to interact with a CosmWasm blockchain. This is the bigger brother of CosmWasmClient.
|
||||
@ -23,14 +21,14 @@ export declare class SigningCosmosClient extends CosmosClient {
|
||||
*
|
||||
* @param apiUrl The URL of a Cosmos SDK light client daemon API (sometimes called REST server or REST API)
|
||||
* @param senderAddress The address that will sign and send transactions using this instance
|
||||
* @param signCallback An asynchonous callback to create a signature for a given transaction. This can be implemented using secure key stores that require user interaction.
|
||||
* @param signer An implementation of OfflineSigner which can provide signatures for transactions, potentially requiring user input.
|
||||
* @param customFees The fees that are paid for transactions
|
||||
* @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns
|
||||
*/
|
||||
constructor(
|
||||
apiUrl: string,
|
||||
senderAddress: string,
|
||||
signCallback: SigningCallback,
|
||||
signer: OfflineSigner,
|
||||
customFees?: Partial<FeeTable>,
|
||||
broadcastMode?: BroadcastMode,
|
||||
);
|
||||
|
||||
39
packages/sdk38/types/wallet.d.ts
vendored
Normal file
39
packages/sdk38/types/wallet.d.ts
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
import { Slip10RawIndex } from "@cosmjs/crypto";
|
||||
import { StdSignature } from "./types";
|
||||
export declare type PrehashType = "sha256" | "sha512" | null;
|
||||
export declare type Algo = "secp256k1" | "ed25519" | "sr25519";
|
||||
export interface AccountData {
|
||||
readonly address: string;
|
||||
readonly algo: Algo;
|
||||
readonly pubkey: Uint8Array;
|
||||
}
|
||||
export interface OfflineSigner {
|
||||
/**
|
||||
* Get AccountData array from wallet. Rejects if not enabled.
|
||||
*/
|
||||
readonly getAccounts: () => Promise<readonly AccountData[]>;
|
||||
/**
|
||||
* Request signature from whichever key corresponds to provided bech32-encoded address. Rejects if not enabled.
|
||||
*/
|
||||
readonly sign: (address: string, message: Uint8Array, prehashType?: PrehashType) => Promise<StdSignature>;
|
||||
}
|
||||
/**
|
||||
* 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 Secp256k1Wallet implements OfflineSigner {
|
||||
static fromMnemonic(
|
||||
mnemonic: string,
|
||||
hdPath?: readonly Slip10RawIndex[],
|
||||
prefix?: string,
|
||||
): Promise<Secp256k1Wallet>;
|
||||
private readonly pubkey;
|
||||
private readonly privkey;
|
||||
private readonly prefix;
|
||||
private readonly algo;
|
||||
private constructor();
|
||||
private get address();
|
||||
getAccounts(): Promise<readonly AccountData[]>;
|
||||
sign(address: string, message: Uint8Array, prehashType?: PrehashType): Promise<StdSignature>;
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
const { SigningCosmWasmClient } = require("@cosmjs/cosmwasm");
|
||||
const { Secp256k1Pen } = require("@cosmjs/sdk38");
|
||||
const { Secp256k1Wallet } = require("@cosmjs/sdk38");
|
||||
const fs = require("fs");
|
||||
|
||||
const httpUrl = "http://localhost:1317";
|
||||
@ -134,8 +134,8 @@ const initDataJade = {
|
||||
};
|
||||
|
||||
async function main() {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet);
|
||||
|
||||
const wasm = fs.readFileSync(__dirname + "/contracts/cw-erc20.wasm");
|
||||
const uploadReceipt = await client.upload(wasm, codeMeta, "Upload ERC20 contract");
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
const { SigningCosmWasmClient } = require("@cosmjs/cosmwasm");
|
||||
const { Secp256k1Pen } = require("@cosmjs/sdk38");
|
||||
const { Secp256k1Wallet } = require("@cosmjs/sdk38");
|
||||
const fs = require("fs");
|
||||
|
||||
const httpUrl = "http://localhost:1317";
|
||||
@ -36,8 +36,8 @@ const luxury = {
|
||||
};
|
||||
|
||||
async function main() {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet);
|
||||
|
||||
const wasm = fs.readFileSync(__dirname + "/contracts/cw-nameservice.wasm");
|
||||
const uploadReceipt = await client.upload(wasm, codeMeta, "Upload Name Service code");
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
const { SigningCosmWasmClient } = require("@cosmjs/cosmwasm");
|
||||
const { coins, Secp256k1Pen } = require("@cosmjs/sdk38");
|
||||
const { coins, Secp256k1Wallet } = require("@cosmjs/sdk38");
|
||||
const fs = require("fs");
|
||||
|
||||
const httpUrl = "http://localhost:1317";
|
||||
@ -38,8 +38,8 @@ const fees = {
|
||||
};
|
||||
|
||||
async function main() {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes), fees);
|
||||
const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic);
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet, fees);
|
||||
|
||||
const wasm = fs.readFileSync(__dirname + "/contracts/staking.wasm");
|
||||
const uploadReceipt = await client.upload(wasm, codeMeta, "Upload Staking code");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user