Releases: atomicassets/atomicassets-contract
Release list
v2.0.0
The AtomicAssets v2 standard contract. Built from main at fd7d730 with CDT 4.1.1.
v2 is an in-place upgrade of the v1 contract. Every existing table keeps its layout and every existing action keeps its signature, so v1 clients and indexers keep working without changes. New capabilities live in new actions and new tables. Upgrading is a setcode and setabi; on-chain state is preserved and no migration action is required.
What v2 adds
1. Reduce max supply
redtemplmax lowers a template's max_supply. It can never be lowered below the supply already issued.
2. Delete unused templates
deltemplate removes a template that has no issued assets, and cleans up its templates2 row.
3. Mutable templates
createtempl2 creates a template carrying mutable data, and settempldata updates it. Each change emits logsetdatatl. Mutable data lives in the new templates2 table alongside the original immutable templates row, so a v1 reader that knows only templates continues to work.
4. Schema media types
setschematyp records per-field media-type descriptors for a schema in the new schematypes table, so a consumer can tell how to render a field rather than inferring it from the field name.
Note for authors: setschematyp replaces the whole descriptor array. Read the stored descriptors before writing, or a client working from a merged or inferred view will write its guesses back to chain.
5. Collection author succession
A two-step author handover. createauswap proposes a new author, and acceptauswap or rejectauswap completes or cancels it. Pending swaps live in the new authorswaps table, and the collection's author changes only on acceptance, so no single party can move a collection unilaterally.
6. A template must permit transfer or burn
createtempl and createtempl2 reject a template whose assets would be neither transferable nor burnable, with A template cannot be both non-transferable and non-burnable. Such an asset could never move and could never be destroyed, so it would hold its owner's RAM permanently with no way to release it.
Both flags are unchanged from v1 and every other combination stays valid: transferable and burnable, transferable only, burnable only. Only the pair set false is refused. The check runs at creation, so templates already in that state keep working exactly as before.
7. Native backing is disabled
backasset now fails unconditionally with Native backing has been deprecated on the AtomicAssets Contract, and mintasset rejects a non-empty tokens_to_back with the same message. No new asset can be backed with fungible tokens after this upgrade. The action remains in the ABI, so the change is invisible to an ABI diff: any integration that calls backasset will start failing at the point of the upgrade and should be updated first.
Value already backed is not stranded:
- Burning an asset still releases its
backed_tokensto the owner's balance, exactly as in v1. withdrawcontinues to work, so balances can still be withdrawn.announcedepoand the deposit path are unchanged.
8. Contract-wide CPU optimizations
The hot collection-authorization checks (check_has_collection_auth, notify_collection_accounts) read only the bytes they need from the collection row through a low-level partial read, rather than loading a row that can carry several KB of serialized data on every schema, template and asset action.
The transfer and offer paths also stop building their failure message on the success path. check(cond, msg) evaluates its message argument before the call, so every successful transfer was concatenating an asset id into a string it then discarded. The check is now written if (!cond) { check(false, msg) }, and the string is built only when the transfer is actually rejected.
Self-service RAM utilities
setrampayer and setlastpayer reassign an asset's RAM payer, emitting logrampayer.
Interface changes
Additive in full. Nothing is removed and no existing struct changes shape. The behavior changes described above are not expressed in the ABI and an ABI diff will not show them. The final surface is 47 actions and 11 tables.
| Added | |
|---|---|
| Actions (12) | createtempl2, settempldata, logsetdatatl, deltemplate, redtemplmax, setschematyp, createauswap, acceptauswap, rejectauswap, setrampayer, setlastpayer, logrampayer |
| Tables (3) | templates2, schematypes, authorswaps |
Existing tables (assets, templates, schemas, collections, config, offers, balances, tokenconfigs) are unchanged. The ABI version moves from eosio::abi/1.1 to 1.2.
Upgrading
A setcode plus setabi. State is preserved and no migration action runs.
Several calls change from success to failure. Every signature is unchanged, so none of this is visible in an ABI diff. Confirm nothing you operate depends on any of them.
backassetfails unconditionally, andmintassetrejects a non-emptytokens_to_back. See Native backing is disabled.createtemplandcreatetempl2reject a template that is both non-transferable and non-burnable. See A template must permit transfer or burn.addcolauthandaddnotifyaccrefuse to extend a list that already holds 24 accounts, andcreatecolrejects more than 24 in either list. V1 enforced no limit, and these lists are walked on every notifying action. A collection already above the cap keeps every entry it has and can still remove them.
Custodial rentals are not part of v2. That implementation is preserved on the archive/v2-custodial-rentals branch.
Artifacts
| Asset | sha256 |
|---|---|
atomicassets.wasm |
962a93e1adde9779d3afb84983cee076c3d2b50b0473c99fb0fe02573a7b7242 |
atomicassets.abi |
b6389fdde10a16f2d94b12bb10a67b676f6449b1293b57cc0b18256652cfef68 |
Verify against the attached SHA256SUMS. On a deployed account the wasm sha256 equals the on-chain code hash, so get_code_hash is sufficient to confirm which bytes are running.
Build and verification
Built with cdt-cpp 4.1.1 from a clean checkout of main at fd7d730. The published ABI is the legacy-compat build: vector<uint8_t> fields render as uint8[] and pair fields keep their first and second spellings, so integrations reading the ABI are unaffected. The VeRT suite is green at 40 suites and 325 tests, one skipped.
Deploying
Pinned by sha256 in the FACINGS monorepo chain-config and deployed through the contracts-deploy workflow. Where the contract account is governed by a multi-party authority, the upgrade reaches chain as an eosio.msig proposal that the authority's signers verify, approve and execute. Signers should check the proposal's wasm sha256 against the table above and its packed ABI against the published .abi, since the chain does not validate setabi payloads.
Credits
AtomicAssets is an open NFT standard created by Pink Network, with stewardship passing from Pink Network to Spielworks and then to FACINGS. The bulk of the v2 contract was authored by t-break (@on-a-t-break). The interface-header fix is from Aaron Cox (@aaroncox, Greymass). Full attribution is in AUTHORS.md.
AtomicAssets v2.0.0-rc5
The AtomicAssets v2 contract, release candidate 5. Built from main with CDT 4.1.1. rc4 describes the full v2 feature set; this candidate corrects one action's boundary behavior and is otherwise identical.
v2 remains a non-breaking, in-place upgrade of the v1 contract. Every existing table keeps its layout and every existing action keeps its signature, so v1 clients and indexers keep working. Upgrading is a setcode (plus setabi on accounts still running v1); existing on-chain state is preserved and no migration action is needed.
This is also the first candidate cut from main. The v2 work merged into the default branch (#9), which until now carried v1 while the release candidates were cut from the integration branch.
Changes since rc4
acceptauswap accepts on its acceptance_date. An author swap only became acceptable a second after the date it advertises. The guard read now > acceptance_date, so the boundary second itself was rejected with a [ 0 ] seconds remaining error. It now rejects only when now < acceptance_date, making the advertised second acceptable. A VeRT regression test pins the boundary and fails against the previous logic.
The same guard built its "seconds remaining" message unconditionally, because check() evaluates both of its arguments before it is called. On every successful accept, acceptance_date - now underflowed as a uint32_t and the resulting string was built and then discarded, spending CPU on the success path of a release whose Feature 8 is CPU optimization. The message is now built only on the path that shows it.
check_format takes its format by const reference. It never writes through the reference. Const states that in the signature and lets callers pass a const format. rc4 had already moved this parameter from by-value to by-reference as part of the Feature 8 work; this completes it.
Documentation and test hygiene. The test-directory listings in README.md and CLAUDE.md now match the tree, including the two directories they omitted entirely. Two template suites locate inline actions by action name rather than by position in the execution trace, so unrelated changes to inline dispatch no longer fail them.
Compatibility with rc4
The ABI is byte-identical to rc4 (b6389fdd…). The action surface, table layouts, and every field spelling are unchanged, so clients, wallets, and indexers built against rc4 work against rc5 without modification. Only the wasm differs, by the acceptauswap guard.
Upgrading an account already on rc4 is a setcode; setabi is a no-op.
Build and verification
Built with cdt-cpp 4.1.1 from a clean checkout of main at fd7d730. The published ABI is the legacy-compat patched build: vector<uint8_t> fields render as uint8[] and pair fields keep their first/second spellings, so integrations that read the ABI do not break. The VeRT suite is green at 40 suites and 325 tests, one skipped.
Artifacts
| asset | sha256 |
|---|---|
atomicassets.wasm |
962a93e1adde9779d3afb84983cee076c3d2b50b0473c99fb0fe02573a7b7242 |
atomicassets.abi |
b6389fdde10a16f2d94b12bb10a67b676f6449b1293b57cc0b18256652cfef68 |
Verify against the attached SHA256SUMS.
Deploying
Pinned by sha256 in the FACINGS monorepo chain-config and deployed via the contracts-deploy workflow using the atomicassets@deploy permission, which is linked to eosio::setcode and eosio::setabi. Coming from rc1 through rc3, the holders cleanup ordering in the rc4 notes still applies. Pre-release, for testnet.
Credits
AtomicAssets is an open NFT standard created by Pink Network, with stewardship passing from Pink Network to Spielworks and then to FACINGS. The bulk of the v2 contract was authored by t-break (@on-a-t-break). The interface-header fix is from Aaron Cox (@aaroncox, Greymass). Full attribution is in AUTHORS.md.
AtomicAssets v2.0.0-rc4
The AtomicAssets v2 contract, release candidate 4. Built from feat/v2-integration with CDT 4.1.1. This describes the whole v2 feature set and supersedes rc1 through rc3.
v2 is a non-breaking, in-place upgrade of the v1 contract. Every existing table keeps its layout and every existing action keeps its signature, so v1 clients and indexers keep working. New capabilities live in new actions and new tables. Upgrading is a setcode (plus setabi on accounts still running v1); existing on-chain state is preserved and no migration action is needed.
Changes since rc3: custodial rentals descoped
Renting and dual ownership (Feature 300) has been removed from the v2 release train so the rest of v2 can ship without it (#27). The implementation is preserved on the archive/v2-custodial-rentals branch; whether and how rentals return has not been decided. The removal takes out:
- Actions:
move,logmove - Table:
holders
The ABI diff against rc3 is exactly these three entries. No other code changed, so everything below stands as reviewed and hardened in the earlier candidates.
Deployment order matters for chains that ran rc1 through rc3: any rows in holders must be cleared (each holder moves the assets back, or the owners burn them) before deploying rc4, because after the upgrade no action can erase them and the RAM they occupy is stranded. Both FACINGS testnets were verified empty before their rc4 deploys. Chains coming from v1 are unaffected.
What v2 adds
Mutable templates (Features 3 and 6). createtempl2 creates a template with mutable data and settempldata updates it (logsetdatatl logs the change). Mutable data lives in the new templates2 table alongside the original immutable templates row. Feature 6 covers the non-transferable / non-burnable rules for templates.
Delete unused templates (Feature 2). deltemplate removes a template that has no issued assets and cleans up its templates2 entry.
Reduce max supply (Feature 1). redtemplmax lowers a template's max_supply, never below the already-issued supply.
Schema media types (Feature 4). setschematyp records per-field media-type metadata for a schema in the new schematypes table.
Collection author succession (Feature 5). A two-step author handover: createauswap proposes a new author, and acceptauswap / rejectauswap complete or cancel it. Pending swaps live in the new authorswaps table; the collection's author changes only on acceptance.
Backed-asset deprecation (Feature 7). Deprecation handling on the deposit, withdraw, and back-asset path.
Contract-wide CPU optimizations (Feature 8). The hot collection-authorization checks (check_has_collection_auth, notify_collection_accounts) read only the bytes they need from the collection row via a low-level partial read, instead of loading the whole row (which can carry several KB of serialized data) into cache on every schema, template, and asset action.
Self-service RAM utilities. setrampayer and setlastpayer reassign an asset's RAM payer, with a logrampayer notification.
New actions
createtempl2, settempldata, logsetdatatl, deltemplate, redtemplmax, setschematyp, createauswap, acceptauswap, rejectauswap, setrampayer, setlastpayer, logrampayer. Existing v1 actions are unchanged. The final surface is 47 actions and 11 tables.
New tables
templates2, schematypes, authorswaps. Existing tables (assets, templates, schemas, collections, config, offers, balances, tokenconfigs) are unchanged.
Fixes carried from rc3
partial_read_collectionauth-path over-read (#12). The Feature 8 partial read deserializednotify_accountseven on the authorized-only path, overflowing its 330-byte buffer once a collection had more than ~38 combined authorized and notify accounts. That threwdatastream attempted to read past the endand brickedcreateschema,createtempl,setschematyp,settempldata, andextendschemafor that collection. The auth path now returns afterauthorized_accounts. Reproduced on jungle4 and covered by a VeRT regression test.createcol24-account cap (#23).addcolauthandaddnotifyacccap each account list at 24, butcreatecolwrote both lists with no size check, which could seed a collection past the read budget in one transaction.createcolnow enforces the same cap.
Build and verification
Built with cdt-cpp 4.1.1. The published ABI is the legacy-compat patched build: vector<uint8_t> fields render as uint8[] and pair fields keep their first/second key/value spellings, so integrations that read the ABI do not break. The VeRT suite is green (40 suites, 324 tests; the two rental suites were removed with the feature).
rc4 is deployed and verified on both FACINGS testnets: the on-chain code hash on the WAX testnet and jungle4 equals the atomicassets.wasm sha256 below, and get_abi on both chains confirms move, logmove, and holders are gone.
Artifacts
| asset | sha256 |
|---|---|
atomicassets.wasm |
86d59e12113442cfb89e84adae89471b6895d66b5c27db77e5cd420dce446316 |
atomicassets.abi |
b6389fdde10a16f2d94b12bb10a67b676f6449b1293b57cc0b18256652cfef68 |
Verify against the attached SHA256SUMS.
Deploying
Pinned by sha256 in the FACINGS monorepo chain-config and deployed via the contracts-deploy workflow using the atomicassets@deploy permission, which is linked to eosio::setcode and eosio::setabi. On an account still running v1 the deploy sends both setcode and setabi; on an account already on a v2 ABI, setabi is skipped as a no-op. Remember the holders cleanup ordering above when coming from an earlier v2 candidate. Pre-release, for testnet.
Credits
AtomicAssets is an open NFT standard created by Pink Network, with stewardship passing from Pink Network to Spielworks and then to FACINGS. The bulk of the v2 contract was authored by t-break (@on-a-t-break). The interface-header fix is from Aaron Cox (@aaroncox, Greymass). Full attribution is in AUTHORS.md.
AtomicAssets v2.0.0-rc3
The AtomicAssets v2 contract, release candidate 3. Built from feat/v2-integration with CDT 4.1.1. This describes the whole v2 feature and supersedes rc1 and rc2.
v2 is a non-breaking, in-place upgrade of the v1 contract. Every existing table keeps its layout and every existing action keeps its signature, so v1 clients and indexers keep working. New capabilities live in new actions and new tables. Upgrading is a setcode (plus setabi on accounts still running v1); existing on-chain state is preserved and no migration action is needed.
What v2 adds
Renting and dual ownership (Feature 300). An asset can be moved to a holder without changing its owner, via the new move action with a logmove notification. Holder state lives in the new holders table: the owner keeps title, the holder has possession, and a burn by the owner clears the holder.
Mutable templates (Features 3 and 6). createtempl2 creates a template with mutable data and settempldata updates it (logsetdatatl logs the change). Mutable data lives in the new templates2 table alongside the original immutable templates row. Feature 6 covers the non-transferable / non-burnable rules for templates.
Delete unused templates (Feature 2). deltemplate removes a template that has no issued assets and cleans up its templates2 entry.
Reduce max supply (Feature 1). redtemplmax lowers a template's max_supply, never below the already-issued supply.
Schema media types (Feature 4). setschematyp records per-field media-type metadata for a schema in the new schematypes table.
Collection author succession (Feature 5). A two-step author handover: createauswap proposes a new author, and acceptauswap / rejectauswap complete or cancel it. Pending swaps live in the new authorswaps table; the collection's author changes only on acceptance.
Backed-asset deprecation (Feature 7). Deprecation handling on the deposit, withdraw, and back-asset path.
Contract-wide CPU optimizations (Feature 8). The hot collection-authorization checks (check_has_collection_auth, notify_collection_accounts) read only the bytes they need from the collection row via a low-level partial read, instead of loading the whole row (which can carry several KB of serialized data) into cache on every schema, template, and asset action.
Self-service RAM utilities. setrampayer and setlastpayer reassign an asset's RAM payer, with a logrampayer notification.
New actions
move, logmove, createtempl2, settempldata, logsetdatatl, deltemplate, redtemplmax, setschematyp, createauswap, acceptauswap, rejectauswap, setrampayer, setlastpayer, logrampayer. Existing v1 actions are unchanged.
New tables
holders, templates2, schematypes, authorswaps. Existing tables (assets, templates, schemas, collections, config, offers, balances, tokenconfigs) are unchanged.
Fixes since rc2
partial_read_collectionauth-path over-read (#12). The Feature 8 partial read deserializednotify_accountseven on the authorized-only path, overflowing its 330-byte buffer once a collection had more than ~38 combined authorized and notify accounts. That threwdatastream attempted to read past the endand brickedcreateschema,createtempl,setschematyp,settempldata, andextendschemafor that collection. The auth path now returns afterauthorized_accounts. Reproduced on jungle4 and covered by a VeRT regression test.createcol24-account cap (#23).addcolauthandaddnotifyacccap each account list at 24, butcreatecolwrote both lists with no size check, which could seed a collection past the read budget in one transaction.createcolnow enforces the same cap.
Build and verification
Built with cdt-cpp 4.1.1. The ABI is the legacy-compat patched build: vector<uint8_t> fields render as uint8[] and pair fields keep their first/second key/value spellings, so integrations that read the ABI do not break. The VeRT suite is green (42 suites). rc3 was deployed to the jungle4 testnet and checked on-chain: the new code hash is live, the formerly-bricking 40-account createschema now succeeds, and createcol rejects a 25-account list.
Artifacts
| asset | sha256 |
|---|---|
atomicassets.wasm |
e0e37ac61dd986a22686e01f431f8d68f42d873934f7ba9a891761675487a7b1 |
atomicassets.abi |
b5963843fa0015c7c3b16b818a7506fe7eee5d38daa91ff29588a4e723a11a74 |
The ABI is unchanged from rc2, since rc3 touches only contract logic. Verify against the attached SHA256SUMS.
Deploying
Pinned by sha256 in the FACINGS monorepo chain-config and deployed via the contracts-deploy workflow using the atomicassets@deploy permission, which is linked to eosio::setcode and eosio::setabi. On an account still running v1 the deploy sends both setcode and setabi; on an account already on a v2 ABI, setabi is skipped as a no-op. Pre-release, for testnet.
Credits
AtomicAssets is an open NFT standard created by Pink Network, with stewardship passing from Pink Network to Spielworks and then to FACINGS. The bulk of the v2 contract was authored by t-break (@on-a-t-break). The interface-header fix is from Aaron Cox (@aaroncox, Greymass). Full attribution is in AUTHORS.md.
AtomicAssets v2.0.0-rc2
AtomicAssets v2.0.0-rc2
Release candidate of the AtomicAssets v2 standard contract, for WAX and Jungle4 testnet smoke testing. Built from feat/v2-integration with CDT 4.1.1. This supersedes v2.0.0-rc1 and adds the self-service RAM utilities.
This is a pre-release for testnet only. It does not include the held partial_read_collection byte-math fix (#12), so this build still carries the auth-path over-read. That needs to be resolved before mainnet.
Artifacts
| asset | sha256 |
|---|---|
atomicassets.wasm |
aa15b3a310b42aea2c42765eab592f74a89e03f6c6f535a7b9230241c49adc98 |
atomicassets.abi |
b5963843fa0015c7c3b16b818a7506fe7eee5d38daa91ff29588a4e723a11a74 |
SHA256SUMS is attached. The ABI is patched back to the legacy key/value (pair) and uint8[] (vector<uint8_t>) spellings the deployed contract uses, so v2 stays a non-breaking superset: every v2 change is additive, and nothing existing is removed, renamed, or retyped. The compiled wasm and the binary wire format are the same with or without that patch.
What's in v2
Feature 1: reduce max template supply
redtemplmax lowers a template's max_supply down to its issued supply. This was previously immutable.
Feature 2: delete unused templates
deltemplate removes a template that has zero issued and circulating assets (it sets deleted_at).
Features 3 and 6: mutable templates, non-burnable/non-transferable
createtempl2 creates a template with explicit immutable and mutable data; settempldata edits the mutable data afterward. The mutable data lives in a new templates2 table, with a logsetdatatl event. Templates can now be non-transferable or non-burnable (the two are mutually exclusive).
Feature 4: per-field media types for schemas
setschematyp attaches media/descriptor types to schema attributes, stored in a new schematypes table.
Feature 5: changing collection authors
createauswap, acceptauswap, and rejectauswap propose, accept, or reject a collection author change, tracked in a new authorswaps table.
Feature 7: deprecating backed assets
Adjusts the deposit/withdraw/back lifecycle to deprecate backed assets.
Feature 8: contract-wide CPU optimizations
partial_read_collection and related read-path changes lower CPU on auth checks. Note that the byte-math fix (#12) for this path is not in this rc.
Feature 300: renting assets (dual ownership)
move and logmove split owner from holder: an asset can be moved to a holder while the owner keeps ownership. A new holders table backs this; the indexer treats holders.holder as the effective holder and falls back to owner when there isn't one.
New in rc2: self-service RAM utilities (#14, @aaroncox)
Before v2, an asset's ram_payer was fixed to the authorized minter and only changed as a side effect of setassetdata. These actions let the current owner take over the RAM cost:
setrampayer(new_payer, asset_id): the owner takes over RAM for a specific asset; the previousram_payeris refunded.setlastpayer(owner, collection_name): the owner takes over RAM for their newest asset in a collection. This is a convenience for post-mint flows.logrampayer: the matching event, consistent with the otherlog*actions.
Testing
The VeRT suite is green in CI: 40 suites, 337 passing, including coverage for setrampayer, setlastpayer, and logrampayer. CI builds with the pinned CDT 4.1.1 and runs the suite on every push and PR to the integration line.
Deploying
Pinned in the AtomicHub monorepo as a type: release ingestion for wax-testnet and jungle4-testnet, with sha256 verification. Deploy by hand through the Deploy Contract workflow, or run cleos set contract atomicassets <dir> atomicassets.wasm atomicassets.abi -p atomicassets@deploy.
Changelog since rc1
- Added
setrampayer,setlastpayer, andlogrampayer, plus VeRT tests for them. - Hardened the
setlastpayeriterator (named lvalue iterator instead of decrementing theend()temporary).
Credits
The bulk of the v2 contract work was authored by t-break (@on-a-t-break), originally in the wax-office-of-inspector-general/atomicassets-contract repo. The self-service RAM utilities are from Aaron Cox (@aaroncox, Greymass). See AUTHORS.md for the full list. AtomicAssets was created by pink.network.
AtomicAssets v2.0.0-rc1
Superseded by v2.0.0-rc2, which adds the self-service RAM utilities (setrampayer, setlastpayer). Use rc2 for new testnet smoke runs.
AtomicAssets v2.0.0-rc1 — release candidate for WAX / Jungle4 testnet smoke testing.
Cut from feat/v2-integration (integrated v2: features 1–8 + 300 — renting/logmove, mutable templates templates2, template delete/reduce-supply, schema media types schematypes, collection author swaps authorswaps, backed-asset deprecation, CPU/byte-math optimizations).
Artifacts
| asset | sha256 |
|---|---|
atomicassets.wasm |
6e671d72e2f6e3135da99c1f42e936184a04aa17daafccc34575791984d25a6e |
atomicassets.abi |
0d20baa3575552fa0a4de5e4a67257c073206e1f5b23148985675607c42b948d |
SHA256SUMS is attached. Built with CDT 4.1.1 (make release).
ABI compatibility
The ABI is patched back to the legacy key/value (pair fields) and uint8[] (vector<uint8_t>) spellings that the currently-deployed contract uses, so v2 is a non-breaking drop-in for existing tools. The compiled wasm and binary wire format are unaffected. Verified a byte-for-byte non-breaking superset of on-chain get_abi(atomicassets).
Notes
- Excludes the held
partial_read_collectionbyte-math fix (PR #12) — this rc carries the auth-path over-read; acceptable for testnet smoke, must be resolved before mainnet GA. - Full VeRT suite green (CI on
feat/v2-integration). - Deploy via the monorepo
Deploy Contractworkflow (atomicassets is wired astype: releaseforwax-testnet+jungle4-testnet, pinned to this tag) orcleos set contract.
Credits
The bulk of the v2 contract work was authored by t-break (@on-a-t-break), originally in the wax-office-of-inspector-general/atomicassets-contract repo. See AUTHORS.md for the full list. AtomicAssets was created by pink.network.