Skip to content

Commit

Permalink
feat: add getTargets method and transferFrom functionality to MNS con…
Browse files Browse the repository at this point in the history
…tract; enhance tests (#730)
  • Loading branch information
Ben-Rey authored Jan 15, 2025
1 parent 2f83f00 commit e83c553
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 4 deletions.
50 changes: 47 additions & 3 deletions src/contracts-wrappers/mns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export const MNS_CONTRACTS = {
const DOMAIN_SEPARATOR_KEY = [0x42]
const TOKEN_ID_KEY_PREFIX = [0x1]
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
const TARGET_KEY_PREFIX = [0x02]
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
const DOMAIN_KEY_PREFIX = [0x3]
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
const ADDRESS_KEY_PREFIX_V2 = [0x6]
Expand Down Expand Up @@ -95,7 +97,7 @@ export class MNS extends SmartContract {
)
}

private async getTokenId(name: string): Promise<bigint> {
async getTokenId(name: string): Promise<bigint> {
const key = Uint8Array.from([
...DOMAIN_SEPARATOR_KEY,
...TOKEN_ID_KEY_PREFIX,
Expand Down Expand Up @@ -130,13 +132,13 @@ export class MNS extends SmartContract {
...OWNED_TOKENS_KEY,
...strToBytes(address),
])
const ownedkeys = await this.provider.getStorageKeys(
const ownedKeys = await this.provider.getStorageKeys(
this.address,
filter,
final
)

const domainKeys = ownedkeys.map((k) => {
const domainKeys = ownedKeys.map((k) => {
const tokenIdBytes = k.slice(filter.length)
return Uint8Array.from([
...DOMAIN_SEPARATOR_KEY,
Expand All @@ -152,6 +154,24 @@ export class MNS extends SmartContract {
return domainsBytes.map((d) => bytesToStr(d))
}

async getTargets(domains: string[], final = false): Promise<string[]> {
const targetDataStoreEntries = domains.map((name) =>
Uint8Array.from([
...DOMAIN_SEPARATOR_KEY,
...TARGET_KEY_PREFIX,
...strToBytes(name),
])
)

const targetsBytes = await this.provider.readStorage(
this.address,
targetDataStoreEntries,
final
)

return targetsBytes.map(bytesToStr)
}

async dnsAllocCost(domain: string, options?: ReadSCOptions): Promise<bigint> {
const res = await this.read(
'dnsAllocCost',
Expand All @@ -163,4 +183,28 @@ export class MNS extends SmartContract {

return U64.fromBytes(res.value)
}

async transferFrom(
domain: string,
currentOwner: string,
newOwner: string,
options?: CallSCOptions
): Promise<Operation> {
const tokenId = await this.getTokenId(domain)
const args = new Args()
.addString(currentOwner)
.addString(newOwner)
.addU256(tokenId)

return await this.call('transferFrom', args, options)
}

async balanceOf(owner: string, options?: ReadSCOptions): Promise<bigint> {
const res = await this.read(
'balanceOf',
new Args().addString(owner),
options
)
return U256.fromBytes(res.value)
}
}
67 changes: 66 additions & 1 deletion test/integration/mns.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MNS } from '../../src'
import { Account, MNS } from '../../src'
import { provider, publicProvider } from './setup'

describe('MNS tests', () => {
Expand Down Expand Up @@ -50,6 +50,71 @@ describe('MNS tests', () => {
res = await mns.resolve(domain)
expect(res).toBe('')
}, 300000)

test('transfer domain', async () => {
const domain = 'trloloooooooooooooooololololzs' + Date.now()
const account2 = await Account.generate()
let operation = await mns.alloc(domain, provider.address, {
coins: 2064100000n,
})

await operation.waitFinalExecution()

// check resolution
let res = await mns.resolve(domain)
expect(res).toBe(provider.address)
// check balance
let balance = await mns.balanceOf(provider.address)
expect(balance).toBeGreaterThan(0n)

// transfer domain
operation = await mns.transferFrom(
domain,
provider.address,
account2.address.toString()
)
await operation.waitFinalExecution()

const domains = await mns.getOwnedDomains(account2.address.toString())
expect(domains).toContain(domain)
const balance2 = await mns.balanceOf(account2.address.toString())
expect(balance2).toBeGreaterThan(0n)
})

test('getTargets', async () => {
// Alloc some domains
const domain1 = 'trloloooooooooooooooololololzs1'
const domain2 = 'trloloooooooooooooooololololzs2'
const domain3 = 'trloloooooooooooooooololololzs3'

const op1 = await mns.alloc(domain1, provider.address, {
coins: 2064100000n,
})
const op2 = await mns.alloc(domain2, provider.address, {
coins: 2064100000n,
})
const op3 = await mns.alloc(domain3, provider.address, {
coins: 2064100000n,
})

await Promise.all([
op1.waitFinalExecution(),
op2.waitFinalExecution(),
op3.waitFinalExecution(),
])

const targets = await mns.getTargets([domain1, domain2, domain3])
expect(targets).toEqual([
provider.address,
provider.address,
provider.address,
])

// Free the domains
mns.free(domain1)
mns.free(domain2)
mns.free(domain3)
})
})

describe('MNS tests using PublicProvider', () => {
Expand Down

1 comment on commit e83c553

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage report for experimental massa-web3

St.
Category Percentage Covered / Total
🟡 Statements 66.19% 1255/1896
🔴 Branches 43.51% 201/462
🔴 Functions 46.54% 222/477
🟡 Lines 66.77% 1248/1869

Test suite run success

134 tests passing in 15 suites.

Report generated by 🧪jest coverage report action from e83c553

Please sign in to comment.