diff --git a/client/src/app.tsx b/client/src/app.tsx
index 127a391..667362a 100644
--- a/client/src/app.tsx
+++ b/client/src/app.tsx
@@ -325,8 +325,8 @@ function Card({
interface InkProps {
alpha?: THREE.Texture;
color: THREE.Color;
- emissive: THREE.Color;
- specular: THREE.Color;
+ emissive?: THREE.Color;
+ specular?: THREE.Color;
side?: THREE.Side;
normal?: THREE.Texture;
shininess?: number;
@@ -532,11 +532,9 @@ function LegendCard({ rotation, ...props }: GroupProps) {
{createPortal(, scene.current)}
-
- {mask && }
+ />}
{
const size = Number(r.headers.get('Content-Length'));
if (size < 5_000) console.error(`Invalid static image on token #${i}`);
expect(size).toBeGreaterThan(5_000);
- expect(r.headers.get('Content-Type')).toBe('image/webp');
expect(r.status).toBe(200);
return r.text()
})
@@ -74,7 +73,6 @@ describe(`${canister}`, () => {
const size = Number(r.headers.get('Content-Length'));
if (size < 5_000) console.error(`Invalid animated image on token #${i}`);
expect(size).toBeGreaterThan(5_000);
- expect(r.headers.get('Content-Type')).toBe('image/webp');
expect(r.status).toBe(200);
return r.text()
})
diff --git a/src/Assets/Assets.test.mo b/src/Assets/Assets.test.mo
index 9ddc100..65cfb98 100644
--- a/src/Assets/Assets.test.mo
+++ b/src/Assets/Assets.test.mo
@@ -28,6 +28,7 @@ let params : Types.Params = {
createAsset("asset3", ["preview", "tag0", "tag1", "tag3"]),
];
colors = [];
+ stockColors = [];
_Admins = Admins.Admins({ admins = [admin] });
};
let a = Assets.Assets(params);
diff --git a/src/Assets/lib.mo b/src/Assets/lib.mo
index 3ea5070..6b202fe 100644
--- a/src/Assets/lib.mo
+++ b/src/Assets/lib.mo
@@ -120,6 +120,9 @@ module {
// TODO: Use token traits instead.
private var colors : [Types.Color] = state.colors;
+ // Colors for legends card stock.
+ private var stockColors : [Types.Color] = state.stockColors;
+
public func restore (backup : Types.State) : () {
for (asset in backup.assets.vals()) {
_putAsset(asset);
@@ -131,6 +134,7 @@ module {
return {
assets = assets.toArray();
colors;
+ stockColors;
};
};
@@ -162,6 +166,11 @@ module {
colors;
};
+ // Get all stock colors.
+ public func getStockColors () : [Types.Color] {
+ stockColors;
+ };
+
////////////////
// Admin API //
@@ -306,6 +315,15 @@ module {
colors := newColors;
};
+ // Configure stock colors.
+ public func configureStockColors (
+ caller : Principal,
+ newColors : [Types.Color],
+ ) : () {
+ assert state._Admins._isAdmin(caller);
+ stockColors := newColors;
+ };
+
};
};
\ No newline at end of file
diff --git a/src/Assets/types.mo b/src/Assets/types.mo
index 0579e92..7ccbeab 100644
--- a/src/Assets/types.mo
+++ b/src/Assets/types.mo
@@ -12,19 +12,14 @@ module Assets {
public type State = {
assets : [Record];
colors : [Color];
+ stockColors : [Color];
};
public type Dependencies = {
_Admins : Admins.Admins;
};
- // TODO: This after upgrading DFX
- // public type Params = State and Dependencies;
- public type Params = {
- assets : [Record];
- colors : [Color];
- _Admins : Admins.Admins;
- };
+ public type Params = State and Dependencies;
public type Asset = {
contentType : Text;
@@ -49,6 +44,8 @@ module Assets {
back : Tag;
border : Tag;
ink : Tag;
+ mask : Tag;
+ stock : Tag;
nri : {
back : Float;
border : Float;
@@ -68,7 +65,7 @@ module Assets {
emissive : Text;
background : Text;
};
- stock : {
+ stockColors: {
base : Text;
specular : Text;
emissive : Text;
diff --git a/src/Http/lib.mo b/src/Http/lib.mo
index f7bc01a..4721200 100644
--- a/src/Http/lib.mo
+++ b/src/Http/lib.mo
@@ -166,7 +166,7 @@ module {
index : Nat,
) : AssetTypes.LegendManifest {
let tokenId = Ext.TokenIdentifier.encode(state.cid, Nat32.fromNat(index));
- let { back; border; ink; mask; normal; } = state._Tokens.nfts(?index)[0];
+ let { back; border; ink; mask; normal; stock; } = state._Tokens.nfts(?index)[0];
let nriBack = switch (Array.find<(Text, Float)>(nri, func ((a, b)) { a == "back-" # back })) {
case (?(_, i)) i;
case _ 0.0;
@@ -183,6 +183,8 @@ module {
back;
border;
ink;
+ mask;
+ stock;
nri = {
back = nriBack;
border = nriBorder;
@@ -236,12 +238,15 @@ module {
};
map;
};
- stock = do {
+ stockColors = do {
var map = {
base = "#000000";
specular = "#000000";
emissive = "#000000";
};
+ for (color in state._Assets.getStockColors().vals()) {
+ if (color.name == stock) map := color;
+ };
map;
};
views = {
@@ -282,6 +287,8 @@ module {
"\t\"back\" : \"" # manifest.back # "\",\n" #
"\t\"border\" : \"" # manifest.border # "\",\n" #
"\t\"ink\" : \"" # manifest.ink # "\",\n" #
+ "\t\"mask\" : \"" # manifest.mask # "\",\n" #
+ "\t\"stock\" : \"" # manifest.stock # "\",\n" #
"\t\"nri\" : {\n" #
"\t\t\"back\" : " # Float.toText(manifest.nri.back) # ",\n" #
"\t\t\"border\" : " # Float.toText(manifest.nri.border) # ",\n" #
@@ -318,9 +325,9 @@ module {
"\t\t\"background\" : \"" # manifest.colors.background # "\"\n" #
"\t},\n" #
"\t\"stock\": {\n" #
- "\t\t\"base\" : \"" # manifest.stock.base # "\",\n" #
- "\t\t\"specular\" : \"" # manifest.stock.specular # "\",\n" #
- "\t\t\"emissive\" : \"" # manifest.stock.emissive # "\"\n" #
+ "\t\t\"base\" : \"" # manifest.stockColors.base # "\",\n" #
+ "\t\t\"specular\" : \"" # manifest.stockColors.specular # "\",\n" #
+ "\t\t\"emissive\" : \"" # manifest.stockColors.emissive # "\"\n" #
"\t},\n" #
"\t\"views\": {\n" #
"\t\t\"flat\" : \"" # manifest.views.flat # "\",\n" #
@@ -457,7 +464,8 @@ module {
let legend = state._Tokens._getMetadata(i);
renderAssetWithTags([
"preview", "side-by-side", "back-" # legend.back,
- "border-" # legend.border, "ink-" # legend.ink
+ "border-" # legend.border, "ink-" # legend.ink,
+ "mask-" # legend.mask, "stock-" # legend.stock
]);
};
};
@@ -484,7 +492,8 @@ module {
let legend = state._Tokens._getMetadata(i);
renderAssetWithTags([
"preview", "animated", "back-" # legend.back,
- "border-" # legend.border, "ink-" # legend.ink
+ "border-" # legend.border, "ink-" # legend.ink,
+ "mask-" # legend.mask, "stock-" # legend.stock
]);
};
};
@@ -543,7 +552,8 @@ module {
if (Text.contains(request.url, #text("type=animated"))) {
return renderAssetWithTags([
"preview", "animated", "back-" # legend.back,
- "border-" # legend.border, "ink-" # legend.ink
+ "border-" # legend.border, "ink-" # legend.ink,
+ "mask-" # legend.mask, "stock-" # legend.stock
]);
};
if (not Text.contains(request.url, #text("type=thumbnail"))) {
@@ -551,7 +561,8 @@ module {
};
renderAssetWithTags([
"preview", "side-by-side", "back-" # legend.back,
- "border-" # legend.border, "ink-" # legend.ink
+ "border-" # legend.border, "ink-" # legend.ink,
+ "mask-" # legend.mask, "stock-" # legend.stock
]);
};
@@ -565,7 +576,8 @@ module {
let legend = state._Tokens._getMetadata(i);
renderAssetWithTags([
"preview", "side-by-side", "back-" # legend.back,
- "border-" # legend.border, "ink-" # legend.ink
+ "border-" # legend.border, "ink-" # legend.ink,
+ "mask-" # legend.mask, "stock-" # legend.stock
]);
};
case _ http404(?"No token at that index.");
@@ -618,12 +630,14 @@ module {
} else if (Text.map(tokens[1], Prim.charToLower) == "webm") {
return renderAssetWithTags([
"preview", "animated", "back-" # legend.back,
- "border-" # legend.border, "ink-" # legend.ink
+ "border-" # legend.border, "ink-" # legend.ink,
+ "mask-" # legend.mask, "stock-" # legend.stock
]);
} else if (Text.map(tokens[1], Prim.charToLower) == "webp") {
return renderAssetWithTags([
"preview", "side-by-side", "back-" # legend.back,
- "border-" # legend.border, "ink-" # legend.ink
+ "border-" # legend.border, "ink-" # legend.ink,
+ "mask-" # legend.mask, "stock-" # legend.stock
]);
} else if (Text.map(tokens[1], Prim.charToLower) == "json") {
return {
diff --git a/src/main.mo b/src/main.mo
index 1fa1aa3..d040bcf 100644
--- a/src/main.mo
+++ b/src/main.mo
@@ -67,6 +67,7 @@ shared ({ caller = creator }) actor class LegendsNFT(
private stable var stableAssets : [AssetTypes.Record] = [];
private stable var stableColors : [AssetTypes.Color] = [];
+ private stable var stableStockColors : [AssetTypes.Color] = [];
// Admins
@@ -111,9 +112,10 @@ shared ({ caller = creator }) actor class LegendsNFT(
system func preupgrade() {
// Preserve assets
- let { colors; assets } = _Assets.backup();
+ let { colors; assets; stockColors; } = _Assets.backup();
stableAssets := assets;
stableColors := colors;
+ stableStockColors := stockColors;
// Preserve admins
stableAdmins := _Admins.toStable();
@@ -187,18 +189,18 @@ shared ({ caller = creator }) actor class LegendsNFT(
//////////////
- system func heartbeat() : async () {
- if (not s_heartbeatOn) return;
+ // system func heartbeat() : async () {
+ // if (not s_heartbeatOn) return;
- // Limit heartbeats
- let now = Time.now();
- if (now - s_heartbeatLastBeat < s_heartbeatIntervalSeconds * 1_000_000_000) return;
- s_heartbeatLastBeat := now;
+ // // Limit heartbeats
+ // let now = Time.now();
+ // if (now - s_heartbeatLastBeat < s_heartbeatIntervalSeconds * 1_000_000_000) return;
+ // s_heartbeatLastBeat := now;
- // Run jobs
- await _Entrepot.cronDisbursements();
- await _Entrepot.cronSettlements();
- };
+ // // Run jobs
+ // await _Entrepot.cronDisbursements();
+ // await _Entrepot.cronSettlements();
+ // };
public shared ({ caller }) func heartbeatSetInterval (
i : Nat
@@ -367,6 +369,7 @@ shared ({ caller = creator }) actor class LegendsNFT(
_Admins;
assets = stableAssets;
colors = stableColors;
+ stockColors = stableStockColors;
});
public shared ({ caller }) func upload (
@@ -436,6 +439,13 @@ shared ({ caller = creator }) actor class LegendsNFT(
_Assets.configureColors(caller, colors);
};
+ public shared ({ caller }) func configureStockColors (
+ colors : [AssetTypes.Color],
+ ) : async () {
+ _captureMetrics();
+ _Assets.configureStockColors(caller, colors);
+ };
+
/////////////
// Tokens //
diff --git a/zsh/configure.zsh b/zsh/configure.zsh
index 1f17d64..0c1eadd 100755
--- a/zsh/configure.zsh
+++ b/zsh/configure.zsh
@@ -35,9 +35,11 @@ payload="$payload})"
dfx canister --network $network call $canister configureMetadata $payload
+
# Initialize CAP
dfx canister --network $network call $canister init
+
# Configure colors
colors="./config/colors/$confname.csv"
[ ! -f $colors ] && { echo "$colors file not found"; exit 99; }
@@ -57,41 +59,22 @@ payload="$payload})"
dfx canister --network $network call $canister configureColors $payload
-# Configure price
-
-config="./config/canisters/$confname.json"
-[ ! -f $config ] && { echo "$config file not found"; exit 99; }
-read -r -d$'\1' price_private price_public <<< $(jq -r '.private_sale_price_e8s, .public_sale_price_e8s' $config)
-
-# dfx canister --network $network call $canister configurePublicSalePrice "( $price_private : nat64, $price_public : nat64 )"
-
-# Configure NRI
-if [[ $canister != "0-the-fool" ]]
-then
- echo "No NRI data yet"
- exit
-fi
+# Configure stocks
+colors="./config/stocks/$confname.csv"
+[ ! -f $colors ] && { echo "$colors file not found"; exit 99; }
+OLDIFS=$IFS
+IFS=','
+payload="(vec {"
+{
+ read # skip headers
+ while read name base specular emissive
+ do
+ if [[ $name == "" ]] continue # skip empty lines
+ payload="$payload record { name = \"$name\"; base = \"$base\"; specular = \"$specular\"; emissive = \"$emissive\"; background = \"#000000\"; };"
+ done
+} < $colors
+IFS=$OLDIFS
+payload="$payload})"
-dfx canister --network $network call $canister configureNri\
- "(vec {\
- record {\"back-fate\"; 0.0000};\
- record {\"back-bordered-saxon\"; 0.5283};\
- record {\"back-worn-saxon\"; 0.9434};\
- record {\"back-saxon\"; 1.0000};\
- record {\"border-thin\"; 0.0000};\
- record {\"border-bare\"; 0.0000};\
- record {\"border-round\"; 0.4615};\
- record {\"border-staggered\"; 0.4615};\
- record {\"border-thicc\"; 0.9231};\
- record {\"border-greek\"; 0.9231};\
- record {\"border-worn-saxon\"; 0.7692};\
- record {\"border-saxon\"; 1.0000};\
- record {\"ink-copper\"; 0.0000};\
- record {\"ink-silver\"; 0.3333};\
- record {\"ink-gold\"; 0.5833};\
- record {\"ink-canopy\"; 0.8056};\
- record {\"ink-rose\"; 0.8611};\
- record {\"ink-spice\"; 0.9444};\
- record {\"ink-midnight\"; 1.0000};\
- })"
\ No newline at end of file
+dfx canister --network $network call $canister configureStockColors "$payload"