Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 09f68a6

Browse files
committed
js tests for spl name service
1 parent d0bd334 commit 09f68a6

File tree

5 files changed

+1582
-560
lines changed

5 files changed

+1582
-560
lines changed

ci/js-test-name-service.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ cd name-service/js
1010
yarn install --pure-lockfile
1111
yarn lint
1212
yarn build
13+
yarn test

name-service/js/package.json

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,36 @@
2323
"prepublish": "tsc",
2424
"lint": "yarn pretty && eslint --max-warnings 0 'src/*.ts'",
2525
"lint:fix": "yarn pretty:fix && eslint 'src/*.ts' --fix",
26-
"pretty": "prettier --check 'src/*.ts'",
27-
"pretty:fix": "prettier --write 'src/*.ts'",
28-
"doc": "yarn typedoc src/index.ts"
26+
"pretty": "prettier --check '{src/*.ts,test/*/*.ts}'",
27+
"pretty:fix": "prettier --write '{src/*.ts,test/*/*.ts}'",
28+
"doc": "yarn typedoc src/index.ts",
29+
"test": "yarn test:unit && yarn test:e2e",
30+
"test:unit": "mocha test/unit",
31+
"test:e2e": "start-server-and-test 'solana-test-validator --bpf-program namesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX ../../target/deploy/spl_name_service.so --reset --quiet' http://localhost:8899/health 'mocha test/e2e'"
2932
},
3033
"prettier": {
3134
"singleQuote": true
3235
},
3336
"devDependencies": {
3437
"@tsconfig/recommended": "^1.0.1",
38+
"@types/chai": "^4.3.4",
39+
"@types/chai-as-promised": "^7.1.5",
40+
"@types/mocha": "^10.0.1",
3541
"@types/node": "^14.14.20",
3642
"@typescript-eslint/eslint-plugin": "^4.0.1",
3743
"@typescript-eslint/parser": "^4.0.1",
3844
"babel-eslint": "^10.1.0",
45+
"chai": "^4.3.7",
46+
"chai-as-promised": "^7.1.1",
3947
"eslint": "^7.8.0",
4048
"eslint-config-prettier": "^6.11.0",
4149
"eslint-plugin-eslint-comments": "^3.2.0",
4250
"eslint-plugin-functional": "^3.0.2",
4351
"eslint-plugin-import": "^2.22.0",
52+
"mocha": "^10.2.0",
4453
"prettier": "^2.2.1",
45-
"ts-node": "^9.1.1",
54+
"start-server-and-test": "^1.15.3",
55+
"ts-node": "^10.9.1",
4656
"typedoc": "^0.22.11",
4757
"typescript": "^4.1.3"
4858
},
@@ -51,5 +61,12 @@
5161
"@solana/web3.js": "^1.11.0",
5262
"bn.js": "^5.1.3",
5363
"borsh": "^0.4.0"
64+
},
65+
"mocha": {
66+
"require": [
67+
"ts-node/register"
68+
],
69+
"recursive": true,
70+
"extension": "ts"
5471
}
5572
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import {
2+
Connection,
3+
Keypair,
4+
LAMPORTS_PER_SOL,
5+
PublicKey,
6+
sendAndConfirmTransaction,
7+
Transaction,
8+
} from '@solana/web3.js';
9+
import chai, { expect } from 'chai';
10+
import chaiAsPromised from 'chai-as-promised';
11+
12+
import {
13+
createNameRegistry,
14+
deleteNameRegistry,
15+
getHashedName,
16+
getNameAccountKey,
17+
NameRegistryState,
18+
reallocNameAccount,
19+
transferNameOwnership,
20+
updateNameRegistryData,
21+
} from '../../src';
22+
23+
chai.use(chaiAsPromised);
24+
const url = 'http://localhost:8899';
25+
26+
describe('Name Service Program', () => {
27+
let connection: Connection;
28+
let payer: Keypair;
29+
let owner: Keypair;
30+
let nameKey: PublicKey;
31+
const name = '.sol';
32+
before(async () => {
33+
connection = new Connection(url, 'confirmed');
34+
payer = Keypair.generate();
35+
const airdropSignature = await connection.requestAirdrop(
36+
payer.publicKey,
37+
4 * LAMPORTS_PER_SOL
38+
);
39+
await connection.confirmTransaction(airdropSignature, 'confirmed');
40+
nameKey = await getNameKey(name);
41+
owner = Keypair.generate();
42+
const space = 20;
43+
const lamports = await connection.getMinimumBalanceForRentExemption(
44+
space + NameRegistryState.HEADER_LEN
45+
);
46+
const inst = await createNameRegistry(
47+
connection,
48+
name,
49+
space,
50+
payer.publicKey,
51+
owner.publicKey,
52+
lamports
53+
);
54+
const tx = new Transaction().add(inst);
55+
await sendAndConfirmTransaction(connection, tx, [payer]);
56+
});
57+
58+
it('Create Name Registery', async () => {
59+
const nameAccount = await NameRegistryState.retrieve(connection, nameKey);
60+
nameAccount.owner.equals(owner.publicKey);
61+
expect(nameAccount.data?.length).to.eql(20);
62+
});
63+
it('Update Name Registery', async () => {
64+
const data = Buffer.from('@Dudl');
65+
const inst = await updateNameRegistryData(connection, name, 0, data);
66+
const tx = new Transaction().add(inst);
67+
await sendAndConfirmTransaction(connection, tx, [payer, owner]);
68+
const nameAccount = await NameRegistryState.retrieve(connection, nameKey);
69+
nameAccount.data?.equals(data);
70+
});
71+
it('Transfer Name Ownership', async () => {
72+
const newOwner = Keypair.generate();
73+
const inst = await transferNameOwnership(
74+
connection,
75+
name,
76+
newOwner.publicKey
77+
);
78+
const tx = new Transaction().add(inst);
79+
await sendAndConfirmTransaction(connection, tx, [payer, owner]);
80+
const nameAccount = await NameRegistryState.retrieve(connection, nameKey);
81+
nameAccount.owner.equals(newOwner.publicKey);
82+
owner = newOwner;
83+
});
84+
it('Realloc Name Account to bigger space', async () => {
85+
const inst = await reallocNameAccount(
86+
connection,
87+
name,
88+
30,
89+
payer.publicKey
90+
);
91+
const tx = new Transaction().add(inst);
92+
await sendAndConfirmTransaction(connection, tx, [payer, owner]);
93+
const nameAccount = await NameRegistryState.retrieve(connection, nameKey);
94+
expect(nameAccount.data?.length).to.eql(30);
95+
});
96+
it('Realloc Name Account to smaller space', async () => {
97+
const inst = await reallocNameAccount(
98+
connection,
99+
name,
100+
10,
101+
payer.publicKey
102+
);
103+
const tx = new Transaction().add(inst);
104+
await sendAndConfirmTransaction(connection, tx, [payer, owner]);
105+
const nameAccount = await NameRegistryState.retrieve(connection, nameKey);
106+
expect(nameAccount.data?.length).to.eql(10);
107+
});
108+
it('Delete Name Registry', async () => {
109+
const inst = await deleteNameRegistry(connection, name, payer.publicKey);
110+
const tx = new Transaction().add(inst);
111+
await sendAndConfirmTransaction(connection, tx, [payer, owner]);
112+
const nameAccount = await connection.getAccountInfo(nameKey);
113+
expect(nameAccount).to.be.null;
114+
});
115+
});
116+
117+
const getNameKey = async (
118+
name: string,
119+
nameClass?: PublicKey,
120+
parentName?: PublicKey
121+
) => {
122+
const hashed_name = await getHashedName(name);
123+
const nameAccountKey = await getNameAccountKey(
124+
hashed_name,
125+
nameClass,
126+
parentName
127+
);
128+
return nameAccountKey;
129+
};
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import {
2+
Keypair,
3+
LAMPORTS_PER_SOL,
4+
PublicKey,
5+
SystemProgram,
6+
} from '@solana/web3.js';
7+
import chai, { expect } from 'chai';
8+
import chaiAsPromised from 'chai-as-promised';
9+
10+
import {
11+
createInstruction,
12+
deleteInstruction,
13+
reallocInstruction,
14+
transferInstruction,
15+
updateInstruction,
16+
} from '../../src';
17+
import { Numberu32, Numberu64 } from '../../src/utils';
18+
19+
chai.use(chaiAsPromised);
20+
21+
describe('SplNameService Instructions', () => {
22+
const nameServiceAddress = new PublicKey(
23+
'namesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX'
24+
);
25+
const nameAccountKey = Keypair.generate().publicKey;
26+
const nameOwnerKey = Keypair.generate().publicKey;
27+
const payerKey = Keypair.generate().publicKey;
28+
const nameClassKey = Keypair.generate().publicKey;
29+
const nameParent = Keypair.generate().publicKey;
30+
const nameParentOwner = Keypair.generate().publicKey;
31+
const name = Buffer.from('hello');
32+
33+
it('createInstruction without class and parent name key', () => {
34+
const instruction = createInstruction(
35+
nameServiceAddress,
36+
SystemProgram.programId,
37+
nameAccountKey,
38+
nameOwnerKey,
39+
payerKey,
40+
name,
41+
new Numberu64(LAMPORTS_PER_SOL),
42+
new Numberu64(10)
43+
);
44+
45+
expect(instruction.keys).to.have.length(6);
46+
instruction.keys[0].pubkey.equals(SystemProgram.programId);
47+
instruction.keys[1].pubkey.equals(payerKey);
48+
instruction.keys[2].pubkey.equals(nameAccountKey);
49+
instruction.keys[3].pubkey.equals(nameOwnerKey);
50+
instruction.keys[4].pubkey.equals(new PublicKey(Buffer.alloc(32)));
51+
instruction.keys[5].pubkey.equals(new PublicKey(Buffer.alloc(32)));
52+
});
53+
54+
it('createInstruction with class and parent name key', () => {
55+
const instruction = createInstruction(
56+
nameServiceAddress,
57+
SystemProgram.programId,
58+
nameAccountKey,
59+
nameOwnerKey,
60+
payerKey,
61+
name,
62+
new Numberu64(LAMPORTS_PER_SOL),
63+
new Numberu64(10),
64+
nameClassKey,
65+
nameParent,
66+
nameParentOwner
67+
);
68+
69+
expect(instruction.keys).to.have.length(7);
70+
instruction.keys[0].pubkey.equals(SystemProgram.programId);
71+
instruction.keys[1].pubkey.equals(payerKey);
72+
instruction.keys[2].pubkey.equals(nameAccountKey);
73+
instruction.keys[3].pubkey.equals(nameOwnerKey);
74+
instruction.keys[4].pubkey.equals(nameClassKey);
75+
instruction.keys[5].pubkey.equals(nameParent);
76+
instruction.keys[6].pubkey.equals(nameParentOwner);
77+
});
78+
79+
it('updateInstruction', () => {
80+
const data = Buffer.from('@Dudl');
81+
const instruction = updateInstruction(
82+
nameServiceAddress,
83+
nameAccountKey,
84+
new Numberu32(0),
85+
data,
86+
nameOwnerKey,
87+
undefined
88+
);
89+
90+
expect(instruction.keys).to.have.length(2);
91+
instruction.keys[0].pubkey.equals(nameAccountKey);
92+
instruction.keys[1].pubkey.equals(nameOwnerKey);
93+
});
94+
95+
it('transferInstruction', () => {
96+
const newOwner = Keypair.generate().publicKey;
97+
const instruction = transferInstruction(
98+
nameServiceAddress,
99+
nameAccountKey,
100+
newOwner,
101+
nameOwnerKey
102+
);
103+
104+
expect(instruction.keys).to.have.length(2);
105+
instruction.keys[0].pubkey.equals(nameAccountKey);
106+
instruction.keys[1].pubkey.equals(nameOwnerKey);
107+
});
108+
109+
it('deleteInstruction', () => {
110+
const instruction = deleteInstruction(
111+
nameServiceAddress,
112+
nameAccountKey,
113+
payerKey,
114+
nameOwnerKey
115+
);
116+
117+
expect(instruction.keys).to.have.length(3);
118+
instruction.keys[0].pubkey.equals(nameAccountKey);
119+
instruction.keys[1].pubkey.equals(nameOwnerKey);
120+
instruction.keys[2].pubkey.equals(payerKey);
121+
});
122+
123+
it('reallocInstruction', () => {
124+
const instruction = reallocInstruction(
125+
nameServiceAddress,
126+
SystemProgram.programId,
127+
payerKey,
128+
nameAccountKey,
129+
nameOwnerKey,
130+
new Numberu32(30)
131+
);
132+
133+
expect(instruction.keys).to.have.length(4);
134+
instruction.keys[0].pubkey.equals(SystemProgram.programId);
135+
instruction.keys[1].pubkey.equals(payerKey);
136+
instruction.keys[2].pubkey.equals(nameAccountKey);
137+
instruction.keys[3].pubkey.equals(nameOwnerKey);
138+
});
139+
});

0 commit comments

Comments
 (0)