-
Notifications
You must be signed in to change notification settings - Fork 3.6k
/
your_coin.ts
137 lines (111 loc) · 5.42 KB
/
your_coin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright © Aptos Foundation
// SPDX-License-Identifier: Apache-2.0
import assert from "assert";
import fs from "fs";
import path from "path";
import { NODE_URL, FAUCET_URL } from "./common";
import { AptosAccount, AptosClient, TxnBuilderTypes, MaybeHexString, HexString, FaucetClient } from "aptos";
/**
This example depends on the MoonCoin.move module having already been published to the destination blockchain.
One method to do so is to use the CLI:
* Acquire the Aptos CLI, see https://aptos.dev/cli-tools/aptos-cli/use-cli/install-aptos-cli
* `pnpm your_coin ~/aptos-core/aptos-move/move-examples/moon_coin`.
* Open another terminal and `aptos move compile --package-dir ~/aptos-core/aptos-move/move-examples/moon_coin --save-metadata --named-addresses MoonCoin=<Alice address from above step>`.
* Return to the first terminal and press enter.
*/
const readline = require("readline").createInterface({
input: process.stdin,
output: process.stdout,
});
class CoinClient extends AptosClient {
constructor() {
super(NODE_URL);
}
/** Register the receiver account to receive transfers for the new coin. */
async registerCoin(coinTypeAddress: HexString, coinReceiver: AptosAccount): Promise<string> {
const rawTxn = await this.generateTransaction(coinReceiver.address(), {
function: "0x1::managed_coin::register",
type_arguments: [`${coinTypeAddress.hex()}::moon_coin::MoonCoin`],
arguments: [],
});
const bcsTxn = await this.signTransaction(coinReceiver, rawTxn);
const pendingTxn = await this.submitTransaction(bcsTxn);
return pendingTxn.hash;
}
/** Transfer the newly created coin to a specified receiver address */
async transferCoin(sender: AptosAccount, receiverAddress: HexString, amount: number | bigint): Promise<string> {
const rawTxn = await this.generateTransaction(sender.address(), {
function: "0x1::aptos_account::transfer_coins",
type_arguments: [`${sender.address()}::moon_coin::MoonCoin`],
arguments: [receiverAddress.hex(), amount],
});
const bcsTxn = await this.signTransaction(sender, rawTxn);
const pendingTxn = await this.submitTransaction(bcsTxn);
return pendingTxn.hash;
}
/** Mints the newly created coin to a specified receiver address */
async mintCoin(minter: AptosAccount, receiverAddress: HexString, amount: number | bigint): Promise<string> {
const rawTxn = await this.generateTransaction(minter.address(), {
function: "0x1::managed_coin::mint",
type_arguments: [`${minter.address()}::moon_coin::MoonCoin`],
arguments: [receiverAddress.hex(), amount],
});
const bcsTxn = await this.signTransaction(minter, rawTxn);
const pendingTxn = await this.submitTransaction(bcsTxn);
return pendingTxn.hash;
}
/** Return the balance of the newly created coin */
async getBalance(accountAddress: MaybeHexString, coinTypeAddress: HexString): Promise<string | number> {
try {
const resource = await this.getAccountResource(
accountAddress,
`0x1::coin::CoinStore<${coinTypeAddress.hex()}::moon_coin::MoonCoin>`,
);
return parseInt((resource.data as any)["coin"]["value"]);
} catch (_) {
return 0;
}
}
}
/** run our demo! */
async function main() {
assert(process.argv.length == 3, "Expecting an argument that points to the moon_coin directory.");
const client = new CoinClient();
const faucetClient = new FaucetClient(NODE_URL, FAUCET_URL);
// Create two accounts, Alice and Bob, and fund Alice but not Bob
const alice = new AptosAccount();
const bob = new AptosAccount();
console.log("\n=== Addresses ===");
console.log(`Alice: ${alice.address()}`);
console.log(`Bob: ${bob.address()}`);
await faucetClient.fundAccount(alice.address(), 100_000_000);
await faucetClient.fundAccount(bob.address(), 100_000_000);
await new Promise<void>((resolve) => {
readline.question("Update the module with Alice's address, compile, and press enter.", () => {
resolve();
readline.close();
});
});
// :!:>publish
const modulePath = process.argv[2];
const packageMetadata = fs.readFileSync(path.join(modulePath, "build", "Examples", "package-metadata.bcs"));
const moduleData = fs.readFileSync(path.join(modulePath, "build", "Examples", "bytecode_modules", "moon_coin.mv"));
console.log("Publishing MoonCoin package.");
let txnHash = await client.publishPackage(alice, new HexString(packageMetadata.toString("hex")).toUint8Array(), [
new TxnBuilderTypes.Module(new HexString(moduleData.toString("hex")).toUint8Array()),
]);
await client.waitForTransaction(txnHash, { checkSuccess: true }); // <:!:publish
console.log(`Bob's initial MoonCoin balance: ${await client.getBalance(bob.address(), alice.address())}.`);
console.log("Alice mints herself some of the new coin.");
txnHash = await client.registerCoin(alice.address(), alice);
await client.waitForTransaction(txnHash, { checkSuccess: true });
txnHash = await client.mintCoin(alice, alice.address(), 100);
await client.waitForTransaction(txnHash, { checkSuccess: true });
console.log("Alice transfers the newly minted coins to Bob.");
txnHash = await client.transferCoin(alice, bob.address(), 100);
await client.waitForTransaction(txnHash, { checkSuccess: true });
console.log(`Bob's updated MoonCoin balance: ${await client.getBalance(bob.address(), alice.address())}.`);
}
if (require.main === module) {
main().then((resp) => console.log(resp));
}