Skip to content

Commit ba0d7bd

Browse files
committed
distribute token
1 parent 2d69d81 commit ba0d7bd

File tree

3 files changed

+136
-1
lines changed

3 files changed

+136
-1
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { type ThirdwebContract, getContract } from "src/contract/contract.js";
2+
import { getBalance } from "src/extensions/erc20/read/getBalance.js";
3+
import { approve } from "src/extensions/erc20/write/approve.js";
4+
import { sendAndConfirmTransaction } from "src/transaction/actions/send-and-confirm-transaction.js";
5+
import { beforeAll, describe, expect, it } from "vitest";
6+
import { ANVIL_CHAIN } from "../../test/src/chains.js";
7+
import { TEST_CLIENT } from "../../test/src/test-clients.js";
8+
import {
9+
TEST_ACCOUNT_A,
10+
TEST_ACCOUNT_B,
11+
TEST_ACCOUNT_C,
12+
TEST_ACCOUNT_D,
13+
} from "../../test/src/test-wallets.js";
14+
import { createTokenByImplConfig } from "./create-token-by-impl-config.js";
15+
import { distributeToken } from "./distribute-token.js";
16+
import { getDeployedEntrypointERC20 } from "./get-entrypoint-erc20.js";
17+
18+
describe.runIf(process.env.TW_SECRET_KEY)("create token by impl config", () => {
19+
let token: ThirdwebContract;
20+
beforeAll(async () => {
21+
// create token
22+
const tokenAddress = await createTokenByImplConfig({
23+
chain: ANVIL_CHAIN,
24+
client: TEST_CLIENT,
25+
account: TEST_ACCOUNT_A,
26+
params: {
27+
name: "Test",
28+
maxSupply: 10_000_000_000n,
29+
},
30+
salt: "salt123",
31+
});
32+
33+
token = getContract({
34+
address: tokenAddress,
35+
client: TEST_CLIENT,
36+
chain: ANVIL_CHAIN,
37+
});
38+
39+
// approve tokens to entrypoint for distribution
40+
const entrypoint = await getDeployedEntrypointERC20({
41+
chain: ANVIL_CHAIN,
42+
client: TEST_CLIENT,
43+
});
44+
45+
const approvalTx = approve({
46+
contract: token,
47+
spender: entrypoint?.address as string,
48+
amountWei: 1000n,
49+
});
50+
await sendAndConfirmTransaction({
51+
transaction: approvalTx,
52+
account: TEST_ACCOUNT_A,
53+
});
54+
});
55+
56+
it("should distrbute tokens to specified recipients", async () => {
57+
const contents = [
58+
{ recipient: TEST_ACCOUNT_B.address, amount: 10n },
59+
{ recipient: TEST_ACCOUNT_C.address, amount: 15n },
60+
{ recipient: TEST_ACCOUNT_D.address, amount: 20n },
61+
];
62+
63+
await distributeToken({
64+
account: TEST_ACCOUNT_A,
65+
client: TEST_CLIENT,
66+
chain: ANVIL_CHAIN,
67+
tokenAddress: token.address,
68+
contents,
69+
});
70+
71+
const balanceB = (
72+
await getBalance({
73+
contract: token,
74+
address: TEST_ACCOUNT_B.address,
75+
})
76+
).value;
77+
78+
const balanceC = (
79+
await getBalance({
80+
contract: token,
81+
address: TEST_ACCOUNT_C.address,
82+
})
83+
).value;
84+
85+
const balanceD = (
86+
await getBalance({
87+
contract: token,
88+
address: TEST_ACCOUNT_D.address,
89+
})
90+
).value;
91+
92+
// admin balance
93+
const balanceA = (
94+
await getBalance({
95+
contract: token,
96+
address: TEST_ACCOUNT_A.address,
97+
})
98+
).value;
99+
100+
expect(balanceB).to.equal(10n);
101+
expect(balanceC).to.equal(15n);
102+
expect(balanceD).to.equal(20n);
103+
104+
expect(balanceA).to.equal(10_000_000_000n - balanceB - balanceC - balanceD);
105+
});
106+
});
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { distributeAsset } from "../extensions/assets/__generated__/AssetEntrypointERC20/write/distributeAsset.js";
2+
import { sendTransaction } from "../transaction/actions/send-transaction.js";
3+
import type { ClientAndChainAndAccount } from "../utils/types.js";
4+
import { getDeployedEntrypointERC20 } from "./get-entrypoint-erc20.js";
5+
import type { DistributeContent } from "./types.js";
6+
7+
type DistrbuteTokenParams = ClientAndChainAndAccount & {
8+
tokenAddress: string;
9+
contents: DistributeContent[];
10+
};
11+
12+
export async function distributeToken(options: DistrbuteTokenParams) {
13+
const entrypoint = await getDeployedEntrypointERC20(options);
14+
15+
if (!entrypoint) {
16+
throw new Error(`Entrypoint not found on chain: ${options.chain.id}`);
17+
}
18+
19+
const transaction = distributeAsset({
20+
contract: entrypoint,
21+
asset: options.tokenAddress,
22+
contents: options.contents,
23+
});
24+
25+
return await sendTransaction({
26+
transaction,
27+
account: options.account,
28+
});
29+
}

packages/thirdweb/src/assets/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export type MarketConfig = {
3030
hookInitData?: string;
3131
};
3232

33-
type DistributeContent = {
33+
export type DistributeContent = {
3434
amount: bigint;
3535
recipient: string;
3636
};

0 commit comments

Comments
 (0)