@ensdomains/ensjs 3.0.0-alpha.1 → 3.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/README.md +2 -0
  2. package/dist/cjs/GqlManager.d.ts +3 -0
  3. package/dist/cjs/GqlManager.js +62 -2
  4. package/dist/cjs/functions/burnFuses.d.ts +3 -2
  5. package/dist/cjs/functions/burnFuses.js +4 -8
  6. package/dist/cjs/functions/createSubname.d.ts +1 -5
  7. package/dist/cjs/functions/createSubname.js +5 -8
  8. package/dist/cjs/functions/deleteSubname.d.ts +3 -3
  9. package/dist/cjs/functions/deleteSubname.js +5 -2
  10. package/dist/cjs/functions/getDNSOwner.d.ts +7 -0
  11. package/dist/cjs/functions/getDNSOwner.js +81 -0
  12. package/dist/cjs/functions/getFuses.js +3 -2
  13. package/dist/cjs/functions/getOwner.js +7 -6
  14. package/dist/cjs/functions/getProfile.d.ts +4 -1
  15. package/dist/cjs/functions/getProfile.js +102 -24
  16. package/dist/cjs/functions/getRecords.d.ts +1 -0
  17. package/dist/cjs/functions/getSpecificRecord.js +22 -5
  18. package/dist/cjs/functions/getSubnames.js +6 -6
  19. package/dist/cjs/functions/setName.d.ts +4 -3
  20. package/dist/cjs/functions/setName.js +5 -10
  21. package/dist/cjs/functions/setRecord.d.ts +18 -0
  22. package/dist/cjs/functions/setRecord.js +27 -0
  23. package/dist/cjs/functions/setRecords.d.ts +4 -2
  24. package/dist/cjs/functions/setRecords.js +14 -12
  25. package/dist/cjs/functions/setResolver.d.ts +4 -4
  26. package/dist/cjs/functions/setResolver.js +6 -12
  27. package/dist/cjs/functions/transferName.d.ts +4 -3
  28. package/dist/cjs/functions/transferName.js +9 -13
  29. package/dist/cjs/functions/transferSubname.d.ts +4 -3
  30. package/dist/cjs/functions/transferSubname.js +5 -8
  31. package/dist/cjs/functions/unwrapName.d.ts +4 -3
  32. package/dist/cjs/functions/unwrapName.js +5 -9
  33. package/dist/cjs/functions/wrapName.d.ts +5 -3
  34. package/dist/cjs/functions/wrapName.js +8 -12
  35. package/dist/cjs/index.d.ts +48 -46
  36. package/dist/cjs/index.js +43 -19
  37. package/dist/cjs/utils/labels.js +5 -4
  38. package/dist/cjs/utils/makeHashIndexes.js +2 -2
  39. package/dist/cjs/utils/normalise.d.ts +1 -0
  40. package/dist/cjs/utils/normalise.js +27 -1
  41. package/dist/cjs/utils/recordHelpers.d.ts +3 -0
  42. package/dist/cjs/utils/recordHelpers.js +42 -15
  43. package/dist/cjs/utils/registerHelpers.js +3 -4
  44. package/dist/cjs/utils/writeTx.d.ts +4 -0
  45. package/dist/cjs/utils/writeTx.js +3 -0
  46. package/dist/esm/GqlManager.d.ts +3 -0
  47. package/dist/esm/GqlManager.js +58 -2
  48. package/dist/esm/functions/burnFuses.d.ts +3 -2
  49. package/dist/esm/functions/burnFuses.js +4 -8
  50. package/dist/esm/functions/createSubname.d.ts +1 -5
  51. package/dist/esm/functions/createSubname.js +5 -8
  52. package/dist/esm/functions/deleteSubname.d.ts +3 -3
  53. package/dist/esm/functions/deleteSubname.js +5 -2
  54. package/dist/esm/functions/getDNSOwner.d.ts +7 -0
  55. package/dist/esm/functions/getDNSOwner.js +51 -0
  56. package/dist/esm/functions/getFuses.js +4 -3
  57. package/dist/esm/functions/getOwner.js +7 -6
  58. package/dist/esm/functions/getProfile.d.ts +4 -1
  59. package/dist/esm/functions/getProfile.js +102 -24
  60. package/dist/esm/functions/getRecords.d.ts +1 -0
  61. package/dist/esm/functions/getSpecificRecord.js +22 -5
  62. package/dist/esm/functions/getSubnames.js +3 -3
  63. package/dist/esm/functions/setName.d.ts +4 -3
  64. package/dist/esm/functions/setName.js +5 -10
  65. package/dist/esm/functions/setRecord.d.ts +18 -0
  66. package/dist/esm/functions/setRecord.js +24 -0
  67. package/dist/esm/functions/setRecords.d.ts +4 -2
  68. package/dist/esm/functions/setRecords.js +14 -12
  69. package/dist/esm/functions/setResolver.d.ts +4 -4
  70. package/dist/esm/functions/setResolver.js +6 -12
  71. package/dist/esm/functions/transferName.d.ts +4 -3
  72. package/dist/esm/functions/transferName.js +9 -13
  73. package/dist/esm/functions/transferSubname.d.ts +4 -3
  74. package/dist/esm/functions/transferSubname.js +5 -8
  75. package/dist/esm/functions/unwrapName.d.ts +4 -3
  76. package/dist/esm/functions/unwrapName.js +5 -9
  77. package/dist/esm/functions/wrapName.d.ts +5 -3
  78. package/dist/esm/functions/wrapName.js +8 -12
  79. package/dist/esm/index.d.ts +48 -46
  80. package/dist/esm/index.js +43 -19
  81. package/dist/esm/utils/labels.js +5 -4
  82. package/dist/esm/utils/makeHashIndexes.js +2 -2
  83. package/dist/esm/utils/normalise.d.ts +1 -0
  84. package/dist/esm/utils/normalise.js +25 -0
  85. package/dist/esm/utils/recordHelpers.d.ts +3 -0
  86. package/dist/esm/utils/recordHelpers.js +40 -14
  87. package/dist/esm/utils/registerHelpers.js +3 -4
  88. package/dist/esm/utils/writeTx.d.ts +4 -0
  89. package/dist/esm/utils/writeTx.js +1 -0
  90. package/package.json +15 -7
  91. package/src/@types/dns-packet/index.d.ts +114 -0
  92. package/src/GqlManager.test.ts +170 -0
  93. package/src/GqlManager.ts +67 -2
  94. package/src/{tests → functions}/batch.test.ts +1 -1
  95. package/src/{tests → functions}/batchWrappers.test.ts +1 -1
  96. package/src/{tests → functions}/burnFuses.test.ts +12 -10
  97. package/src/functions/burnFuses.ts +9 -11
  98. package/src/{tests → functions}/createSubname.test.ts +12 -16
  99. package/src/functions/createSubname.ts +7 -13
  100. package/src/{tests → functions}/deleteSubname.test.ts +32 -32
  101. package/src/functions/deleteSubname.ts +9 -12
  102. package/src/functions/getDNSOwner.test.ts +122 -0
  103. package/src/functions/getDNSOwner.ts +61 -0
  104. package/src/{tests → functions}/getExpiry.test.ts +1 -1
  105. package/src/{tests → functions}/getFuses.test.ts +12 -10
  106. package/src/functions/getFuses.ts +4 -3
  107. package/src/{tests → functions}/getHistory.test.ts +1 -1
  108. package/src/{tests → functions}/getName.test.ts +1 -1
  109. package/src/{tests → functions}/getNames.test.ts +1 -1
  110. package/src/{tests → functions}/getOwner.test.ts +14 -2
  111. package/src/functions/getOwner.ts +7 -7
  112. package/src/{tests → functions}/getProfile.test.ts +45 -12
  113. package/src/functions/getProfile.ts +151 -24
  114. package/src/functions/getRecords.ts +1 -0
  115. package/src/{tests → functions}/getResolver.test.ts +1 -1
  116. package/src/{tests → functions}/getSpecificRecord.test.ts +1 -1
  117. package/src/functions/getSpecificRecord.ts +28 -8
  118. package/src/{tests → functions}/getSubnames.test.ts +1 -1
  119. package/src/functions/getSubnames.ts +68 -66
  120. package/src/{tests → functions}/makeCommitment.test.ts +1 -1
  121. package/src/functions/normalise.test.ts +22 -0
  122. package/src/{tests → functions}/setName.test.ts +3 -2
  123. package/src/functions/setName.ts +15 -17
  124. package/src/functions/setRecord.test.ts +100 -0
  125. package/src/functions/setRecord.ts +63 -0
  126. package/src/{tests → functions}/setRecords.test.ts +12 -10
  127. package/src/functions/setRecords.ts +22 -16
  128. package/src/{tests → functions}/setResolver.test.ts +12 -15
  129. package/src/functions/setResolver.ts +15 -20
  130. package/src/{tests → functions}/transferName.test.ts +30 -31
  131. package/src/functions/transferName.ts +19 -22
  132. package/src/{tests → functions}/transferSubname.test.ts +34 -34
  133. package/src/functions/transferSubname.ts +21 -13
  134. package/src/{tests → functions}/unwrapName.test.ts +24 -23
  135. package/src/functions/unwrapName.ts +20 -15
  136. package/src/{tests → functions}/wrapName.test.ts +19 -19
  137. package/src/functions/wrapName.ts +20 -22
  138. package/src/index.ts +115 -26
  139. package/src/tests/populateTransaction.test.ts +40 -0
  140. package/src/tests/signerInjection.test.ts +46 -0
  141. package/src/tests/withProvider.test.ts +1 -1
  142. package/src/utils/labels.ts +6 -4
  143. package/src/utils/makeHashIndexes.ts +4 -4
  144. package/src/utils/normalise.ts +29 -0
  145. package/src/utils/recordHelpers.ts +52 -18
  146. package/src/utils/registerHelpers.ts +3 -4
  147. package/src/utils/writeTx.ts +6 -0
@@ -0,0 +1,40 @@
1
+ import { ethers } from 'ethers'
2
+ import { ENS } from '..'
3
+ import setup from '../tests/setup'
4
+
5
+ let ENSInstance: ENS
6
+ let revert: Awaited<ReturnType<typeof setup>>['revert']
7
+ let provider: ethers.providers.JsonRpcProvider
8
+ let accounts: string[]
9
+
10
+ beforeAll(async () => {
11
+ ;({ ENSInstance, revert, provider } = await setup())
12
+ accounts = await provider.listAccounts()
13
+ })
14
+
15
+ afterAll(async () => {
16
+ await revert()
17
+ })
18
+
19
+ jest.setTimeout(20000)
20
+
21
+ describe('populateTransaction', () => {
22
+ beforeEach(async () => {
23
+ await revert()
24
+ })
25
+ it('should return a transaction successfully', async () => {
26
+ const tx = await ENSInstance.setName('fleek.eth')
27
+ expect(tx).toBeTruthy()
28
+ if (tx) {
29
+ await tx.wait()
30
+ expect(tx.hash).toBeTruthy()
31
+ }
32
+ })
33
+ it('should return a populated transaction successfully', async () => {
34
+ const tx = await ENSInstance.setName.populateTransaction('fleek.eth')
35
+ expect(tx).toBeTruthy()
36
+ if (tx) {
37
+ expect(tx).not.toHaveProperty('hash')
38
+ }
39
+ })
40
+ })
@@ -0,0 +1,46 @@
1
+ import { ContractTransaction, ethers } from 'ethers'
2
+ import { ENS } from '..'
3
+ import setup from '../tests/setup'
4
+
5
+ let ENSInstance: ENS
6
+ let revert: Awaited<ReturnType<typeof setup>>['revert']
7
+ let provider: ethers.providers.JsonRpcProvider
8
+ let accounts: string[]
9
+
10
+ beforeAll(async () => {
11
+ ;({ ENSInstance, revert, provider } = await setup())
12
+ accounts = await provider.listAccounts()
13
+ })
14
+
15
+ afterAll(async () => {
16
+ await revert()
17
+ })
18
+
19
+ jest.setTimeout(20000)
20
+
21
+ describe('Signer Injection', () => {
22
+ beforeEach(async () => {
23
+ await revert()
24
+ })
25
+ it('should return a transaction successfully for a custom signer', async () => {
26
+ const signer = provider.getSigner(accounts[3])
27
+ const tx = await ENSInstance.setName('fleek.eth', {
28
+ signer,
29
+ })
30
+ expect(tx).toBeTruthy()
31
+ if (tx) {
32
+ await tx.wait()
33
+ expect(tx.from).toBe(accounts[3])
34
+ }
35
+ })
36
+ it('should return a transaction succesfully for a custom signer index', async () => {
37
+ const tx = (await ENSInstance.setName('fleek.eth', {
38
+ addressOrIndex: 3,
39
+ })) as ContractTransaction
40
+ expect(tx).toBeTruthy()
41
+ if (tx) {
42
+ await tx.wait()
43
+ expect(tx.from).toBe(accounts[3])
44
+ }
45
+ })
46
+ })
@@ -1,6 +1,6 @@
1
1
  import { ethers } from 'ethers'
2
2
  import { ENS } from '..'
3
- import setup from './setup'
3
+ import setup from '../tests/setup'
4
4
 
5
5
  let ENSInstance: ENS
6
6
  let providerFake: ethers.providers.JsonRpcProvider
@@ -1,6 +1,8 @@
1
1
  import { solidityKeccak256 } from 'ethers/lib/utils'
2
2
  import { truncateFormat } from './format'
3
3
 
4
+ const hasLocalStorage = typeof localStorage !== 'undefined'
5
+
4
6
  export const labelhash = (input: string) =>
5
7
  solidityKeccak256(['string'], [input])
6
8
 
@@ -17,7 +19,7 @@ export function decodeLabelhash(hash: string) {
17
19
  throw Error('Expected encoded labelhash to have a length of 66')
18
20
  }
19
21
 
20
- return `${hash.slice(1, -1)}`
22
+ return `0x${hash.slice(1, -1)}`
21
23
  }
22
24
 
23
25
  export function encodeLabelhash(hash: string) {
@@ -37,13 +39,13 @@ export function isEncodedLabelhash(hash: string) {
37
39
  }
38
40
 
39
41
  function getLabels() {
40
- return localStorage
42
+ return hasLocalStorage
41
43
  ? JSON.parse(localStorage.getItem('ensjs:labels') as string) || {}
42
44
  : {}
43
45
  }
44
46
 
45
47
  function _saveLabel(hash: string, label: any) {
46
- if (!localStorage) return hash
48
+ if (!hasLocalStorage) return hash
47
49
  const labels = getLabels()
48
50
  localStorage.setItem(
49
51
  'ensjs:labels',
@@ -106,7 +108,7 @@ export function decryptName(name: string) {
106
108
  export const truncateUndecryptedName = (name: string) => truncateFormat(name)
107
109
 
108
110
  export function checkLocalStorageSize() {
109
- if (!localStorage) return 'Empty (0 KB)'
111
+ if (!hasLocalStorage) return 'Empty (0 KB)'
110
112
  let allStrings = ''
111
113
  for (const key in window.localStorage) {
112
114
  if (Object.prototype.hasOwnProperty.call(window.localStorage, key)) {
@@ -1,9 +1,9 @@
1
- import { ethers } from 'ethers'
1
+ import { namehash } from './normalise'
2
2
 
3
3
  export const makeOtherIndexes = (data: string, findStr: string) =>
4
4
  Array.from(data.matchAll(findStr as any)).map((x: any) => x.index / 2 - 1)
5
5
 
6
6
  export const makeNamehashIndexes = (data: string, name: string) =>
7
- Array.from(
8
- data.matchAll(ethers.utils.namehash(name).substring(2) as any),
9
- ).map((x: any) => x.index / 2 - 1)
7
+ Array.from(data.matchAll(namehash(name).substring(2) as any)).map(
8
+ (x: any) => x.index / 2 - 1,
9
+ )
@@ -1,4 +1,33 @@
1
+ import { concat, hexlify, keccak256, toUtf8Bytes } from 'ethers/lib/utils'
1
2
  import uts46 from 'idna-uts46-hx/uts46bundle.js'
3
+ import { decodeLabelhash, isEncodedLabelhash } from './labels'
4
+
5
+ const zeros = new Uint8Array(32)
6
+ zeros.fill(0)
2
7
 
3
8
  export const normalise = (name: string) =>
4
9
  name ? uts46.toUnicode(name, { useStd3ASCII: true }) : name
10
+
11
+ export const namehash = (name: string): string => {
12
+ let result: string | Uint8Array = zeros
13
+
14
+ if (name) {
15
+ const labels = name.split('.')
16
+
17
+ for (var i = labels.length - 1; i >= 0; i--) {
18
+ let labelSha: string
19
+ if (isEncodedLabelhash(labels[i])) {
20
+ labelSha = decodeLabelhash(labels[i])
21
+ } else {
22
+ const normalised = normalise(labels[i])
23
+ labelSha = keccak256(toUtf8Bytes(normalised))
24
+ }
25
+
26
+ result = keccak256(concat([result, labelSha]))
27
+ }
28
+ } else {
29
+ result = hexlify(zeros)
30
+ }
31
+
32
+ return result as string
33
+ }
@@ -33,6 +33,47 @@ export const generateSetAddr = (
33
33
  )
34
34
  }
35
35
 
36
+ export type RecordTypes = 'contentHash' | 'text' | 'addr'
37
+
38
+ export type RecordInput<T extends RecordTypes> = T extends 'contentHash'
39
+ ? string
40
+ : RecordItem
41
+
42
+ export function generateSingleRecordCall<T extends RecordTypes>(
43
+ namehash: string,
44
+ resolver: PublicResolver,
45
+ type: T,
46
+ ): (record: RecordInput<T>) => string {
47
+ if (type === 'contentHash') {
48
+ return (_r: RecordInput<T>) => {
49
+ const record = _r as string
50
+ let _contentHash = ''
51
+ if (record !== _contentHash) {
52
+ const encoded = encodeContenthash(record)
53
+ if (encoded.error) throw new Error(encoded.error)
54
+ _contentHash = encoded.encoded as string
55
+ }
56
+ return resolver.interface.encodeFunctionData('setContenthash', [
57
+ namehash,
58
+ _contentHash,
59
+ ])
60
+ }
61
+ } else {
62
+ return (_r: RecordInput<T>) => {
63
+ const record = _r as RecordItem
64
+ if (type === 'text') {
65
+ return resolver.interface.encodeFunctionData('setText', [
66
+ namehash,
67
+ record.key,
68
+ record.value,
69
+ ])
70
+ } else {
71
+ return generateSetAddr(namehash, record.key, record.value, resolver)
72
+ }
73
+ }
74
+ }
75
+ }
76
+
36
77
  export const generateRecordCallArray = (
37
78
  namehash: string,
38
79
  records: RecordOptions,
@@ -41,31 +82,24 @@ export const generateRecordCallArray = (
41
82
  const calls: string[] = []
42
83
 
43
84
  if (records.contentHash) {
44
- const contentHash =
45
- records.contentHash === '' ? '' : encodeContenthash(records.contentHash)
46
- const data = (resolver?.interface.encodeFunctionData as any)(
47
- 'setContenthash',
48
- [namehash, contentHash],
49
- )
85
+ const data = generateSingleRecordCall(
86
+ namehash,
87
+ resolver,
88
+ 'contentHash',
89
+ )(records.contentHash)
50
90
  data && calls.push(data)
51
91
  }
52
92
 
53
93
  if (records.texts && records.texts.length > 0) {
54
- records.texts.forEach(({ key, value }: RecordItem) => {
55
- const data = resolver?.interface.encodeFunctionData('setText', [
56
- namehash,
57
- key,
58
- value,
59
- ])
60
- data && calls.push(data)
61
- })
94
+ records.texts
95
+ .map(generateSingleRecordCall(namehash, resolver, 'text'))
96
+ .forEach((call) => calls.push(call))
62
97
  }
63
98
 
64
99
  if (records.coinTypes && records.coinTypes.length > 0) {
65
- records.coinTypes.forEach(({ key, value }: RecordItem) => {
66
- const data = generateSetAddr(namehash, key, value, resolver!)
67
- data && calls.push(data)
68
- })
100
+ records.coinTypes
101
+ .map(generateSingleRecordCall(namehash, resolver, 'addr'))
102
+ .forEach((call) => calls.push(call))
69
103
  }
70
104
 
71
105
  return calls
@@ -3,6 +3,7 @@ import type { FuseOptions } from '../@types/FuseOptions'
3
3
  import type { PublicResolver } from '../generated'
4
4
  import generateFuseInput from './generateFuseInput'
5
5
  import { labelhash } from './labels'
6
+ import { namehash } from './normalise'
6
7
  import { generateRecordCallArray, RecordOptions } from './recordHelpers'
7
8
 
8
9
  export const randomSecret = () => {
@@ -28,11 +29,9 @@ export const makeCommitment = ({
28
29
  fuses?: FuseOptions
29
30
  }) => {
30
31
  const label = labelhash(name.split('.')[0])
31
- const namehash = utils.namehash(name)
32
+ const hash = namehash(name)
32
33
  const resolverAddress = resolver.address
33
- const data = records
34
- ? generateRecordCallArray(namehash, records, resolver)
35
- : []
34
+ const data = records ? generateRecordCallArray(hash, records, resolver) : []
36
35
  const secret = randomSecret()
37
36
  const fuseData = fuses ? generateFuseInput(fuses) : '0'
38
37
 
@@ -0,0 +1,6 @@
1
+ import { JsonRpcSigner } from '@ethersproject/providers'
2
+ import type { PopulatedTransaction } from 'ethers'
3
+
4
+ export default (signer: JsonRpcSigner, populate: boolean) =>
5
+ (tx: PopulatedTransaction) =>
6
+ populate ? tx : signer.sendTransaction(tx)