Skip to content

Commit

Permalink
refactor(aens)!: replace aens methods with Name class
Browse files Browse the repository at this point in the history
BREAKING CHANGE: aens* methods removed
Use Name class instead.
```diff
-await aeSdk.aensPreclaim('example.chain')
+const name = new Name('example.chain', aeSdk.getContext())
+await name.preclaim()
```
Accordingly for other methods:
```
aensRevoke => Name:revoke
aensUpdate => Name:update
aensTransfer => Name:transfer
aensQuery => Name:getState
aensClaim => Name:claim
aensBid => Name:bid
```
  • Loading branch information
davidyuk committed May 31, 2024
1 parent 9653784 commit e2495bc
Show file tree
Hide file tree
Showing 9 changed files with 532 additions and 585 deletions.
106 changes: 23 additions & 83 deletions docs/guides/aens.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ Claiming an AENS name requires you (at least) 2 transactions:

### Pre-claim
```js
// imports
import { AeSdk, Name } from '@aeternity/aepp-sdk'

const aeSdk = new AeSdk({ ... }) // init the SDK instance with AeSdk class

const name = 'testNameForTheGuide.chain'
// `getContext` is used to bind AeSdk to Name instance
// e.g. if you change the node in AeSdk it also would be changed in Name.
// Alternatively, you need to provide `onAccount`, `onNode` options.
const name = new Name('testNameForTheGuide.chain', aeSdk.getContext())

const preClaimTx = await aeSdk.aensPreclaim(name)
const preClaimTx = await name.preclaim()
console.log(preClaimTx)

/*
Expand All @@ -42,10 +45,7 @@ console.log(preClaimTx)
version: 1
},
rawTx: 'tx_+JkLAfhCuEBgFzAL0bPDufmzDq0558vaKtrIyRpNxCYVtkgnJjBrxDpQZHkfbwG+oRuBUAfgfrAKF0lO9mRI1zq0H6bXIq8KuFH4TyEBoQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAhKhA+Jawe/spFaw823K+U59CWx+xD1i34gngUPiAAKJqv/fhg8dpTI4AAAGc20E',
height: 449499,
claim: [Function: claim],
salt: 7595805618692717,
commitmentId: 'cm_2igvW9egddKh77gDdE8mjotmL8PzE7Tf2Q639Q5stUqWQoEfap'
height: 449499
}
*/
```
Expand All @@ -57,24 +57,20 @@ the same `salt` and it should be signed with the same private key as `pre-claim`
- As the `pre-claim` is required to avoid front running it is recommended to wait with the actual `claim` until at least 1 key block has been mined so that nobody knows which name you aim to claim.
- The corresponding `claim` cannot be included in the same key block anyway. The protocol doesn't allow that.
- You should check if the name is still available before performing a `pre-claim`. The protocol itself doesn't reject a `pre-claim` transaction if the name isn't available anymore.
- As you can see above in the logs the result (`preClaimTx`) of the `aensPreclaim` has bound a `claim` function that you can make use of to perform the actual claim.
- In case you want to perform the actual claim at a later point you should remember the `salt` that has been used for the `pre-claim`

### Claim
This example assumes that you perform the actual `claim` manually by having remembered the required `salt`. In most cases you'd probably use the `claim` function that is bound to the result of the `aensPreclaim` function directly (see above).
This example assumes that you did a `pre-claim` before and kept an instance of Name.

Depending on the length of the name in punycode the actual `claim` will result in direct ownership of the AENS name or start an auction:

- `Name length` > 12: ownership of the name is immediately transferred to your account
- `Name length` <= 12: an `auction` is started

```js
const salt = 7595805618692717 // salt from pre-claim transaction

// the minimum `nameFee` will be automatically generated by sdk
// in case you want to provide a custom `nameFee` you can so so by providing it in an options object
// in case of starting the auction `nameFee` will be the starting bid
const claimTx = await aeSdk.aensClaim(name, salt)
const claimTx = await name.claim()
console.log(claimTx)

/*
Expand All @@ -95,15 +91,7 @@ console.log(claimTx)
type: 'NameClaimTx',
version: 2
},
rawTx: 'tx_+KILAfhCuECVba2mm3Un3nrN9U+LpuB2wzqDDmAzXwvc+9sVkpkcALzqm14p7kGqyt8pwjGTyKeLM9lp+KgXWF4PHmHz0WAPuFr4WCACoQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAhOZdGVzdE5hbWVGb3JUaGVHdWlkZS5jaGFpboca/FhPr2JtiCfFAveE1kAAhg9HjghAAADilhgr',
id: 'nm_1Cz5HGY8PMWZxNrM6s51CtsJZDU3DDT1LdmpEipa3DRghyGz5',
owner: 'ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
pointers: [],
ttl: 629507,
update: [Function (anonymous)],
transfer: [Function (anonymous)],
revoke: [Function (anonymous)],
extendTtl: [Function (anonymous)]
rawTx: 'tx_+KILAfhCuECVba2mm3Un3nrN9U+LpuB2wzqDDmAzXwvc+9sVkpkcALzqm14p7kGqyt8pwjGTyKeLM9lp+KgXWF4PHmHz0WAPuFr4WCACoQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAhOZdGVzdE5hbWVGb3JUaGVHdWlkZS5jaGFpboca/FhPr2JtiCfFAveE1kAAhg9HjghAAADilhgr'
}
*/
```
Expand All @@ -123,16 +111,17 @@ In case there is an auction running for a name you want to claim you need to pla
```js
import { computeBidFee, computeAuctionEndBlock } from '@aeternity/aepp-sdk'

const name = 'auctiontest1.chain'
const name = new Name('auctiontest1.chain', aeSdk.getContext())

const startFee = ... // request from middleware, e.g. https://testnet.aeternity.io/mdw/name/auctiontest1.chain
const increment = 0.05 // 5%, the minimum required increment

// startFee is OPTIONAL and defaults to minimum calculated fee for the name in general
// startFee MUST be at least the nameFee of the last bid
// increment is OPTIONAL and defaults to 0.05
const nameFee = computeBidFee(name, { startFee, increment })
const bidTx = await aeSdk.aensBid(name, nameFee)
// `name.value` is a name as string
const nameFee = computeBidFee(name.value, { startFee, increment })
const bidTx = await name.bid(nameFee)

console.log(bidTx)
console.log(`BID PLACED AT ${bidTx.blockHeight} WILL END AT ${computeAuctionEndBlock(name, bidTx.blockHeight)}`)
Expand All @@ -155,8 +144,7 @@ console.log(`BID PLACED AT ${bidTx.blockHeight} WILL END AT ${computeAuctionEndB
type: 'NameClaimTx',
version: 2
},
rawTx: 'tx_+JQLAfhCuEAv2HQoyLa7krHpcQAsPpWdP+6PJYzdPSifmwNIgpWZtyrdgVD+IGMzzAqxkOQEDeAwc/Oh+dfXPBZpNslCNFgBuEz4SiACoQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAhiSYXVjdGlvbnRlc3QxLmNoYWluAIgr2JC2AnPkAIYPBly7UAAAm/NY1g==',
nameFee: BigNumber { s: 1, e: 18, c: [ 31594, 34250000000000 ] }
rawTx: 'tx_+JQLAfhCuEAv2HQoyLa7krHpcQAsPpWdP+6PJYzdPSifmwNIgpWZtyrdgVD+IGMzzAqxkOQEDeAwc/Oh+dfXPBZpNslCNFgBuEz4SiACoQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAhiSYXVjdGlvbnRlc3QxLmNoYWluAIgr2JC2AnPkAIYPBly7UAAAm/NY1g=='
}
BID PLACED AT 449693 WILL END AT 479453
*/
Expand All @@ -178,7 +166,6 @@ Now that you own your AENS name you might want to update it in order to:
```js
import { getDefaultPointerKey, encode, Encoding } from '@aeternity/aepp-sdk'

const name = 'testNameForTheGuide.chain'
const oracle = 'ok_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk'
const pointers = {
account_pubkey: 'ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
Expand All @@ -188,13 +175,7 @@ const pointers = {
channel: 'ch_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
}

// using aeSdk directly (instance of AeSdk class)
const nameUpdateTx = await aeSdk.aensUpdate(name, pointers)

// OR using the instance of a name
const nameInstance = await aeSdk.aensQuery(name)
const nameUpdateTx = await nameInstance.update(pointers)

const nameUpdateTx = await name.update(pointers)
console.log(nameUpdateTx)

/*
Expand All @@ -216,41 +197,23 @@ console.log(nameUpdateTx)
type: 'NameUpdateTx',
version: 1
},
rawTx: 'tx_+NQLAfhCuED6aLVAlIfcqczlZ4XzOjG3U23l5+egPFDVEKTSMuL0Zj18jUG6ctJxGGQubNoANFcwQl79T7w0dG4+FV7Qn3AKuIz4iiIBoQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAhuhAgB4Gsn+dalOdWvHXJd+3LBBiO9HsZoHIF2/aQ4n/bbagwK/IPLxjmFjY291bnRfcHVia2V5oQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAoMBSniGEDBirVAAAJ7I9GA=',
id: 'nm_1Cz5HGY8PMWZxNrM6s51CtsJZDU3DDT1LdmpEipa3DRghyGz5',
owner: 'ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
pointers: [
{
id: 'ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
key: 'account_pubkey'
}
],
ttl: 629855,
update: [Function (anonymous)],
transfer: [Function (anonymous)],
revoke: [Function (anonymous)],
extendTtl: [Function (anonymous)]
rawTx: 'tx_+NQLAfhCuED6aLVAlIfcqczlZ4XzOjG3U23l5+egPFDVEKTSMuL0Zj18jUG6ctJxGGQubNoANFcwQl79T7w0dG4+FV7Qn3AKuIz4iiIBoQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAhuhAgB4Gsn+dalOdWvHXJd+3LBBiO9HsZoHIF2/aQ4n/bbagwK/IPLxjmFjY291bnRfcHVia2V5oQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAoMBSniGEDBirVAAAJ7I9GA='
}
*/
```

Note:

- If you provide an empty pointers object and don't set `extendPointers` to `true` all of your current pointers will be removed.
- If you provide a non-empty object of pointers to that function while using `extendPointers` the SDK will merge the existing pointers with those provided.
- In case there already exists an account pointer and you provide an accounts address in the array the old account pointer will be overwritten
- It's also possible to pass additional [transaction options](../transaction-options.md#nameupdatetx) here, too.

### Extend TTL while keeping pointers
In case you want to extend a name using a custom TTL and keep the current pointers you can do this as follows:

```js
const name = 'testNameForTheGuide.chain'

// using aeSdk directly (instance of AeSdk class
const nameUpdateTx = await aeSdk.aensUpdate(name, {}, { nameTtl: 100000, extendPointers: true })

// OR using the instance of a name
const nameInstance = await aeSdk.aensQuery(name)
const nameUpdateTx = await nameInstance.update({}, { nameTtl: 100000, extendPointers: true })

const nameUpdateTx = await name.extendTtl(100000)
console.log(nameUpdateTx)

/*
Expand All @@ -277,25 +240,12 @@ console.log(nameUpdateTx)
*/
```

Note:

- If you provide a non-empty array of pointers to that function while using `extendPointers` the SDK will merge the existing pointers with those provided.
- In case there already exists an account pointer and you provide an accounts address in the array the old account pointer will be overwritten
- If you provide an empty array and don't set `extendPointers` to `true` all of your current pointers will be removed.

## 3. Transfer ownership of a name
In some cases you might want to transfer the ownership of a name to another account. Of course this is also possible and you can do that as follows:

```js
const recipient = 'ak_...'

// using aeSdk directly (instance of AeSdk class)
const nameTransferTx = await aeSdk.aensTransfer(name, recipient)

// OR using the instance of a name
const nameInstance = await aeSdk.aensQuery(name)
const nameTransferTx = await nameInstance.transfer(recipient)

const nameTransferTx = await name.transfer(recipient)
console.log(nameTransferTx)

/*
Expand Down Expand Up @@ -323,13 +273,7 @@ console.log(nameTransferTx)
## 4. Revoke a name
In case you want to revoke a name prior to its expiration for whatever reason you can do that as follows:
```js
// using aeSdk directly (instance of AeSdk class)
const nameRevokeTx = await aeSdk.aensRevoke(name)

// OR using the instance of a name
const nameInstance = await aeSdk.aensQuery(name)
const nameRevokeTx = await nameInstance.revoke()

const nameRevokeTx = await name.revoke()
console.log(nameRevokeTx)

/*
Expand Down Expand Up @@ -364,10 +308,6 @@ It is possible to authorize a Sophia contract to manage an AENS name on behalf o
This functionality could for example be used to build an AENS marketplace.

```js
// imports

const aeSdk = new AeSdk({ ... }) // init the SDK instance with AeSdk class

const contractAddress = 'ct_asd2ks...'
// AENS name
const name = 'example.chain'
Expand Down
5 changes: 2 additions & 3 deletions src/AeSdkMethods.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as chainMethods from './chain';
import { sendTransaction } from './send-transaction';
import * as aensMethods from './aens';
import * as spendMethods from './spend';
import * as oracleMethods from './oracle';
import createDelegationSignature from './contract/delegation-signature';
Expand All @@ -19,7 +18,6 @@ export type OnAccount = Encoded.AccountAddress | AccountBase | undefined;
const methods = {
...chainMethods,
sendTransaction,
...aensMethods,
...spendMethods,
...oracleMethods,
createDelegationSignature,
Expand Down Expand Up @@ -90,7 +88,8 @@ class AeSdkMethods {

// TODO: omit onNode from options, because it is already in context
async buildTx(options: TxParamsAsync): Promise<Encoded.Transaction> {
return buildTxAsync({ ...this.getContext(), ...options });
// TODO: remove `any` at the same time as AeSdk class
return buildTxAsync({ ...this.getContext() as any, ...options });
}
}

Expand Down
Loading

0 comments on commit e2495bc

Please sign in to comment.