Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 57 additions & 18 deletions src/contract/token/nft/NftUtils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const {Address} = require("../../../utils");
const {Cell} = require("../../../boc");
const {Address, BN} = require('../../../utils');
const {Cell} = require('../../../boc');

const SNAKE_DATA_PREFIX = 0x00;
const CHUNK_DATA_PREFIX = 0x01;
Expand Down Expand Up @@ -61,33 +61,72 @@ const parseOffchainUriCell = (cell) => {
}

/**
* @param bs {BitString}
* @param cursor {number}
* @param bits {number}
* @return {BigInt}
* @param bs {BitString}
* @param cursor {number}
* @param bits {number}
*
* @return {BN}
*/
const readIntFromBitString = (bs, cursor, bits) => {
let n = BigInt(0);
const readUintFromBitString = (bs, cursor, bits) => {

if ((cursor + bits) > bs.getUsedBits()) {
throw new Error(`Bit string offset is out of bounds`);
}

let n = new BN(0);
for (let i = 0; i < bits; i++) {
n *= BigInt(2);
n += BigInt(bs.get(cursor + i));
n.imuln(2);
n.iaddn(bs.get(cursor + i) ? 1 : 0);
}

return n;

}

/**
* @param cell {Cell}
* @return {Address|null}
*/
const parseAddress = cell => {
let n = readIntFromBitString(cell.bits, 3, 8);
if (n > BigInt(127)) {
n = n - BigInt(256);

const type = readUintFromBitString(cell.bits, 0, 2);

// "none" address
if (type.eqn(0b00)) {
return null;
}
const hashPart = readIntFromBitString(cell.bits, 3 + 8, 256);
if (n.toString(10) + ":" + hashPart.toString(16) === '0:0') return null;
const s = n.toString(10) + ":" + hashPart.toString(16).padStart(64, '0');
return new Address(s);

// internal standard address
if (type.eqn(0b10)) {

/**
* addr_std$10
* anycast:(Maybe Anycast)
* workchain_id:int8
* address:bits256
* = MsgAddressInt;
*/

// @todo: implement readInt (signed) method instead
let workchainId = readUintFromBitString(cell.bits, 3, 8);
if (workchainId.gtn(127)) {
workchainId.isubn(256);
}

const hashPart = readUintFromBitString(cell.bits, 3 + 8, 256);

return new Address(
workchainId.toString() + ':' +
hashPart.toString(16).padStart(64, '0')
);

} else {
throw new Error(
`Unsupported address type: 0b${type.toString(2, 2)}`
);

}

};

/**
Expand Down Expand Up @@ -117,4 +156,4 @@ module.exports = {
createOffchainUriCell,
parseOffchainUriCell,
getRoyaltyParams
};
};