Skip to content

Commit

Permalink
add ton storage support in ton dns
Browse files Browse the repository at this point in the history
  • Loading branch information
tolya-yanot committed Dec 29, 2022
1 parent a821484 commit 253cb5c
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 14 deletions.
2 changes: 1 addition & 1 deletion dist/tonweb.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tonweb",
"version": "0.0.58",
"version": "0.0.59",
"description": "TonWeb - JavaScript API for TON blockchain",
"main": "src/index.js",
"types": "dist/types/index.d.ts",
Expand Down
12 changes: 10 additions & 2 deletions src/contract/dns/Dns.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ const {
DNS_CATEGORY_NEXT_RESOLVER,
DNS_CATEGORY_SITE,
DNS_CATEGORY_WALLET,
DNS_CATEGORY_STORAGE,
createSmartContractAddressRecord,
createAdnlAddressRecord,
createStorageBagIdRecord,
createNextResolverRecord,
parseSmartContractAddressRecord,
parseAdnlAddressRecord,
parseStorageBagIdRecord,
parseSiteRecord,
parseNextResolverRecord,
dnsResolve
} = require("./DnsUtils");
Expand Down Expand Up @@ -36,7 +40,7 @@ class Dns {
* @param domain {string} e.g "sub.alice.ton"
* @param category {string | undefined} category of requested DNS record, null for all categories
* @param oneStep {boolean | undefined} non-recursive
* @returns {Promise<Cell | Address | AdnlAddress | null>}
* @returns {Promise<Cell | Address | AdnlAddress | StorageBagId | null>}
*/
async resolve(domain, category, oneStep) {
const rootDnsAddress = await this.getRootDnsAddress();
Expand All @@ -53,7 +57,7 @@ class Dns {

/**
* @param domain {string} e.g "sub.alice.ton"
* @returns {Promise<AdnlAddress | null>}
* @returns {Promise<AdnlAddress | StorageBagId | null>}
*/
getSiteAddress(domain) {
return this.resolve(domain, DNS_CATEGORY_SITE);
Expand All @@ -63,12 +67,16 @@ class Dns {
Dns.resolve = dnsResolve;
Dns.createSmartContractAddressRecord = createSmartContractAddressRecord;
Dns.createAdnlAddressRecord = createAdnlAddressRecord;
Dns.createStorageBagIdRecord = createStorageBagIdRecord;
Dns.createNextResolverRecord = createNextResolverRecord;
Dns.parseNextResolverRecord = parseNextResolverRecord;
Dns.parseAdnlAddressRecord = parseAdnlAddressRecord;
Dns.parseStorageBagIdRecord = parseStorageBagIdRecord;
Dns.parseSiteRecord = parseSiteRecord;
Dns.parseSmartContractAddressRecord = parseSmartContractAddressRecord;
Dns.DNS_CATEGORY_NEXT_RESOLVER = DNS_CATEGORY_NEXT_RESOLVER;
Dns.DNS_CATEGORY_WALLET = DNS_CATEGORY_WALLET;
Dns.DNS_CATEGORY_SITE = DNS_CATEGORY_SITE;
Dns.DNS_CATEGORY_STORAGE = DNS_CATEGORY_STORAGE;

module.exports.default = Dns;
2 changes: 1 addition & 1 deletion src/contract/dns/DnsCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class DnsCollection extends Contract {
* @param domain {string} e.g "sub.alice.ton"
* @param category? {string} category of requested DNS record, null for all categories
* @param oneStep? {boolean} non-recursive
* @returns {Promise<Cell | Address | AdnlAddress | null>}
* @returns {Promise<Cell | Address | AdnlAddress | StorageBagId | null>}
*/
async resolve(domain, category, oneStep) {
const myAddress = await this.getAddress();
Expand Down
2 changes: 1 addition & 1 deletion src/contract/dns/DnsItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class DnsItem extends Contract {
* @param domain {string} e.g "sub.alice.ton"
* @param category? {string} category of requested DNS record, null for all categories
* @param oneStep? {boolean} non-recursive
* @returns {Promise<Cell | Address | AdnlAddress | null>}
* @returns {Promise<Cell | Address | AdnlAddress | StorageBagId | null>}
*/
async resolve(domain, category, oneStep) {
const myAddress = await this.getAddress();
Expand Down
51 changes: 46 additions & 5 deletions src/contract/dns/DnsUtils.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
const {parseAddress} = require("../token/nft/NftUtils");
const {AdnlAddress, BN, sha256, bytesToHex, bytesToBase64} = require("../../utils");
const {AdnlAddress, StorageBagId, BN, sha256, bytesToHex, bytesToBase64} = require("../../utils");
const {Cell} = require("../../boc");

const DNS_CATEGORY_NEXT_RESOLVER = 'dns_next_resolver'; // Smart Contract address
const DNS_CATEGORY_WALLET = 'wallet'; // Smart Contract address
const DNS_CATEGORY_SITE = 'site'; // ADNL address
const DNS_CATEGORY_SITE = 'site'; // ADNL address or Bag ID
const DNS_CATEGORY_STORAGE = 'storage'; // Bag ID

/**
* @param category {string | undefined}
Expand Down Expand Up @@ -41,6 +42,17 @@ const createAdnlAddressRecord = (adnlAddress) => {
return cell;
}

/**
* @param storageBagId {StorageBagId}
* @return {Cell}
*/
const createStorageBagIdRecord = (storageBagId) => {
const cell = new Cell();
cell.bits.writeUint(0x7473, 16);
cell.bits.writeBytes(storageBagId.bytes);
return cell;
}

/**
* @param smartContractAddress {Address}
* @return {Cell}
Expand Down Expand Up @@ -91,14 +103,37 @@ const parseAdnlAddressRecord = (cell) => {
return new AdnlAddress(bytes);
}

/**
* @param cell {Cell}
* @return {StorageBagId}
*/
const parseStorageBagIdRecord = (cell) => {
if (cell.bits.array[0] !== 0x74 || cell.bits.array[1] !== 0x73) throw new Error('Invalid dns record value prefix');
const bytes = cell.bits.array.slice(2, 2 + 32); // skip prefix - first 16 bits
return new StorageBagId(bytes);
}

/**
* @param cell {Cell}
* @return {AdnlAddress|StorageBagId|null}
*/
const parseSiteRecord = (cell) => {
if (!cell) return null;
if (cell.bits.array[0] === 0xad || cell.bits.array[1] === 0x01) {
return parseAdnlAddressRecord(cell);
} else {
return parseStorageBagIdRecord(cell);
}
}

/**
* @private
* @param provider {HttpProvider}
* @param dnsAddress {string} address of dns smart contract
* @param rawDomainBytes {Uint8Array}
* @param category {string | undefined} category of requested DNS record
* @param oneStep {boolean | undefined} non-recursive
* @returns {Promise<Cell | Address | AdnlAddress | null>}
* @returns {Promise<Cell | Address | AdnlAddress | StorageBagId | null>}
*/
const dnsResolveImpl = async (provider, dnsAddress, rawDomainBytes, category, oneStep) => {
const len = rawDomainBytes.length * 8;
Expand Down Expand Up @@ -140,7 +175,9 @@ const dnsResolveImpl = async (provider, dnsAddress, rawDomainBytes, category, on
} else if (category === DNS_CATEGORY_WALLET) {
return cell ? parseSmartContractAddressRecord(cell) : null;
} else if (category === DNS_CATEGORY_SITE) {
return cell ? parseAdnlAddressRecord(cell) : null;
return cell ? parseSiteRecord(cell) : null;
} else if (category === DNS_CATEGORY_STORAGE) {
return cell ? parseStorageBagIdRecord(cell) : null;
} else {
return cell;
}
Expand Down Expand Up @@ -214,7 +251,7 @@ const domainToBytes = (domain) => {
* @param domain {string} e.g "sub.alice.ton"
* @param category {string | undefined} category of requested DNS record
* @param oneStep {boolean | undefined} non-recursive
* @returns {Promise<Cell | Address | AdnlAddress | null>}
* @returns {Promise<Cell | Address | AdnlAddress | StorageBagId | null>}
*/
const dnsResolve = async (provider, rootDnsAddress, domain, category, oneStep) => {
const rawDomainBytes = domainToBytes(domain);
Expand All @@ -226,13 +263,17 @@ module.exports = {
DNS_CATEGORY_NEXT_RESOLVER,
DNS_CATEGORY_SITE,
DNS_CATEGORY_WALLET,
DNS_CATEGORY_STORAGE,
categoryToBN,
domainToBytes,
createSmartContractAddressRecord,
createAdnlAddressRecord,
createNextResolverRecord,
parseSmartContractAddressRecord,
parseAdnlAddressRecord,
parseStorageBagIdRecord,
parseSiteRecord,
parseNextResolverRecord,
createStorageBagIdRecord,
dnsResolve
};
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const TransportWebUSB = require("@ledgerhq/hw-transport-webusb").default;
const TransportWebHID = require("@ledgerhq/hw-transport-webhid").default;
const BluetoothTransport = require("@ledgerhq/hw-transport-web-ble").default;
const {Dns, DnsCollection, DnsItem} = require("./contract/dns").default;
const version = '0.0.58';
const version = '0.0.59';

class TonWeb {
constructor(provider) {
Expand Down
50 changes: 50 additions & 0 deletions src/utils/StorageBagId.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const {hexToBytes, bytesToHex} = require("./Utils");

class StorageBagId {
/**
* @param anyForm {string | Uint8Array | StorageBagId}
*/
static isValid(anyForm) {
try {
new StorageBagId(anyForm);
return true;
} catch (e) {
return false;
}
}

/**
* @param anyForm {string | Uint8Array | StorageBagId}
*/
constructor(anyForm) {
if (anyForm == null) {
throw "Invalid address";
}

if (anyForm instanceof StorageBagId) {
this.bytes = anyForm.bytes;
} else if (anyForm instanceof Uint8Array) {
if (anyForm.length !== 32) {
throw new Error('invalid bag id bytes length');
}
this.bytes = anyForm;
} else if (typeof anyForm === 'string') {
if (anyForm.length !== 64) {
throw new Error('invalid bag id hex length');
}
this.bytes = hexToBytes(anyForm);
} else {
throw new Error('unsupported type')
}
}

toHex() {
let hex = bytesToHex(this.bytes);
while (hex.length < 64) {
hex = '0' + hex;
}
return hex;
}
}

module.exports.default = StorageBagId;
2 changes: 2 additions & 0 deletions src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const {

const Address = require("./Address").default;
const AdnlAddress = require("./AdnlAddress").default;
const StorageBagId = require("./StorageBagId").default;

// ton://transfer/EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG
// ton://transfer/EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG?amount=1000000000
Expand Down Expand Up @@ -110,6 +111,7 @@ function formatTransferUrl(address, amount, text) {
module.exports = {
Address,
AdnlAddress,
StorageBagId,
BN,
nacl,
sha256,
Expand Down

0 comments on commit 253cb5c

Please sign in to comment.